<commit_before>package service_test

import (
	"errors"

	testplanbuilder "github.com/cloudfoundry/cli/cf/actors/plan_builder/fakes"
	testapi "github.com/cloudfoundry/cli/cf/api/fakes"
	. "github.com/cloudfoundry/cli/cf/commands/service"
	"github.com/cloudfoundry/cli/cf/configuration/core_config"
	"github.com/cloudfoundry/cli/cf/models"
	testcmd "github.com/cloudfoundry/cli/testhelpers/commands"
	testconfig "github.com/cloudfoundry/cli/testhelpers/configuration"
	testreq "github.com/cloudfoundry/cli/testhelpers/requirements"
	testterm "github.com/cloudfoundry/cli/testhelpers/terminal"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"

	. "github.com/cloudfoundry/cli/testhelpers/matchers"
)

var _ = Describe("update-service command", func() {
	var (
		ui                  *testterm.FakeUI
		config              core_config.Repository
		requirementsFactory *testreq.FakeReqFactory
		serviceRepo         *testapi.FakeServiceRepo
		planBuilder         *testplanbuilder.FakePlanBuilder
		offering1           models.ServiceOffering
	)

	BeforeEach(func() {
		ui = &testterm.FakeUI{}
		config = testconfig.NewRepositoryWithDefaults()
		requirementsFactory = &testreq.FakeReqFactory{LoginSuccess: true, TargetedSpaceSuccess: true}
		serviceRepo = &testapi.FakeServiceRepo{}
		planBuilder = &testplanbuilder.FakePlanBuilder{}

		offering1 = models.ServiceOffering{}
		offering1.Label = "cleardb"
		offering1.Plans = []models.ServicePlanFields{{
			Name: "spark",
			Guid: "cleardb-spark-guid",
		}, {
			Name: "flare",
			Guid: "cleardb-flare-guid",
		},
		}

		//serviceRepo.FindServiceOfferingsForSpaceByLabelReturns.ServiceOfferings = []models.ServiceOffering{offering1}
	})

	var callUpdateService = func(args []string) bool {
		cmd := NewUpdateService(ui, config, serviceRepo, planBuilder)
		return testcmd.RunCommand(cmd, args, requirementsFactory)
	}

	Describe("requirements", func() {
		It("passes when logged in and a space is targeted", func() {
			Expect(callUpdateService([]string{"cleardb"})).To(BeTrue())
		})

		It("fails with usage when not provided exactly one arg", func() {
			Expect(callUpdateService([]string{})).To(BeFalse())
		})

		It("fails when not logged in", func() {
			requirementsFactory.LoginSuccess = false
			Expect(callUpdateService([]string{"cleardb", "spark", "my-cleardb-service"})).To(BeFalse())
		})

		It("fails when a space is not targeted", func() {
			requirementsFactory.TargetedSpaceSuccess = false
			Expect(callUpdateService([]string{"cleardb", "spark", "my-cleardb-service"})).To(BeFalse())
		})
	})
	Context("when no flags are passed", func() {
		Context("when there is an err finding the instance", func() {
			It("returns an error", func() {
				serviceRepo.FindInstanceByNameErr = true

				callUpdateService([]string{"some-stupid-not-real-instance"})

				Expect(ui.Outputs).To(ContainSubstrings(
					[]string{"Error finding instance"},
					[]string{"FAILED"},
				))
			})
		})
		Context("when the instance exists", func() {
			It("prints a user indicating it is a no-op", func() {
				callUpdateService([]string{"my-service"})

				Expect(ui.Outputs).To(ContainSubstrings(
					[]string{"OK"},
					[]string{"No changes were made"},
				))
			})
		})
	})
	Context("when the plan flag is passed", func() {
		BeforeEach(func() {
			serviceInstance := models.ServiceInstance{
				ServiceInstanceFields: models.ServiceInstanceFields{
					Name: "my-service-instance",
					Guid: "my-service-instance-guid",
				},
				ServiceOffering: models.ServiceOfferingFields{
					Label: "murkydb",
					Guid:  "murkydb-guid",
				},
			}

			servicePlans := []models.ServicePlanFields{{
				Name: "spark",
				Guid: "murkydb-spark-guid",
			}, {
				Name: "flare",
				Guid: "murkydb-flare-guid",
			},
			}
			serviceRepo.FindInstanceByNameServiceInstance = serviceInstance
			planBuilder.GetPlansForServiceForOrgReturns(servicePlans, nil)

		})
		It("successfully updates a service", func() {
			callUpdateService([]string{"-p", "flare", "my-service-instance"})

			Expect(ui.Outputs).To(ContainSubstrings(
				[]string{"Updating service", "my-service", "as", "my-user", "..."},
				[]string{"OK"},
			))
			Expect(serviceRepo.FindInstanceByNameName).To(Equal("my-service-instance"))
			serviceGuid, orgName := planBuilder.GetPlansForServiceForOrgArgsForCall(0)
			Expect(serviceGuid).To(Equal("murkydb-guid"))
			Expect(orgName).To(Equal("my-org"))
			Expect(serviceRepo.UpdateServiceInstanceArgs.InstanceGuid).To(Equal("my-service-instance-guid"))
			Expect(serviceRepo.UpdateServiceInstanceArgs.PlanGuid).To(Equal("murkydb-flare-guid"))
		})

		Context("when there is an err finding the instance", func() {
			It("returns an error", func() {
				serviceRepo.FindInstanceByNameErr = true

				callUpdateService([]string{"-p", "flare", "some-stupid-not-real-instance"})

				Expect(ui.Outputs).To(ContainSubstrings(
					[]string{"Error finding instance"},
					[]string{"FAILED"},
				))
			})
		})
		Context("when there is an err finding service plans", func() {
			It("returns an error", func() {
				planBuilder.GetPlansForServiceForOrgReturns(nil, errors.New("Error fetching plans"))

				callUpdateService([]string{"-p", "flare", "some-stupid-not-real-instance"})

				Expect(ui.Outputs).To(ContainSubstrings(
					[]string{"Error fetching plans"},
					[]string{"FAILED"},
				))
			})
		})
		Context("when the plan specified does not exist in the service offering", func() {
			It("returns an error", func() {
				callUpdateService([]string{"-p", "not-a-real-plan", "instance-without-service-offering"})

				Expect(ui.Outputs).To(ContainSubstrings(
					[]string{"Plan does not exist for the murkydb service"},
					[]string{"FAILED"},
				))
			})
		})
		Context("when there is an error updating the service instance", func() {
			It("returns an error", func() {
				serviceRepo.UpdateServiceInstanceReturnsErr = true
				callUpdateService([]string{"-p", "flare", "my-service-instance"})

				Expect(ui.Outputs).To(ContainSubstrings(
					[]string{"Error updating service instance"},
					[]string{"FAILED"},
				))
			})
		})
	})
})
<commit_msg>Remove commented line in update_service_test<commit_after>package service_test

import (
	"errors"

	testplanbuilder "github.com/cloudfoundry/cli/cf/actors/plan_builder/fakes"
	testapi "github.com/cloudfoundry/cli/cf/api/fakes"
	. "github.com/cloudfoundry/cli/cf/commands/service"
	"github.com/cloudfoundry/cli/cf/configuration/core_config"
	"github.com/cloudfoundry/cli/cf/models"
	testcmd "github.com/cloudfoundry/cli/testhelpers/commands"
	testconfig "github.com/cloudfoundry/cli/testhelpers/configuration"
	testreq "github.com/cloudfoundry/cli/testhelpers/requirements"
	testterm "github.com/cloudfoundry/cli/testhelpers/terminal"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"

	. "github.com/cloudfoundry/cli/testhelpers/matchers"
)

var _ = Describe("update-service command", func() {
	var (
		ui                  *testterm.FakeUI
		config              core_config.Repository
		requirementsFactory *testreq.FakeReqFactory
		serviceRepo         *testapi.FakeServiceRepo
		planBuilder         *testplanbuilder.FakePlanBuilder
		offering1           models.ServiceOffering
	)

	BeforeEach(func() {
		ui = &testterm.FakeUI{}
		config = testconfig.NewRepositoryWithDefaults()
		requirementsFactory = &testreq.FakeReqFactory{LoginSuccess: true, TargetedSpaceSuccess: true}
		serviceRepo = &testapi.FakeServiceRepo{}
		planBuilder = &testplanbuilder.FakePlanBuilder{}

		offering1 = models.ServiceOffering{}
		offering1.Label = "cleardb"
		offering1.Plans = []models.ServicePlanFields{{
			Name: "spark",
			Guid: "cleardb-spark-guid",
		}, {
			Name: "flare",
			Guid: "cleardb-flare-guid",
		},
		}

	})

	var callUpdateService = func(args []string) bool {
		cmd := NewUpdateService(ui, config, serviceRepo, planBuilder)
		return testcmd.RunCommand(cmd, args, requirementsFactory)
	}

	Describe("requirements", func() {
		It("passes when logged in and a space is targeted", func() {
			Expect(callUpdateService([]string{"cleardb"})).To(BeTrue())
		})

		It("fails with usage when not provided exactly one arg", func() {
			Expect(callUpdateService([]string{})).To(BeFalse())
		})

		It("fails when not logged in", func() {
			requirementsFactory.LoginSuccess = false
			Expect(callUpdateService([]string{"cleardb", "spark", "my-cleardb-service"})).To(BeFalse())
		})

		It("fails when a space is not targeted", func() {
			requirementsFactory.TargetedSpaceSuccess = false
			Expect(callUpdateService([]string{"cleardb", "spark", "my-cleardb-service"})).To(BeFalse())
		})
	})
	Context("when no flags are passed", func() {
		Context("when there is an err finding the instance", func() {
			It("returns an error", func() {
				serviceRepo.FindInstanceByNameErr = true

				callUpdateService([]string{"some-stupid-not-real-instance"})

				Expect(ui.Outputs).To(ContainSubstrings(
					[]string{"Error finding instance"},
					[]string{"FAILED"},
				))
			})
		})
		Context("when the instance exists", func() {
			It("prints a user indicating it is a no-op", func() {
				callUpdateService([]string{"my-service"})

				Expect(ui.Outputs).To(ContainSubstrings(
					[]string{"OK"},
					[]string{"No changes were made"},
				))
			})
		})
	})
	Context("when the plan flag is passed", func() {
		BeforeEach(func() {
			serviceInstance := models.ServiceInstance{
				ServiceInstanceFields: models.ServiceInstanceFields{
					Name: "my-service-instance",
					Guid: "my-service-instance-guid",
				},
				ServiceOffering: models.ServiceOfferingFields{
					Label: "murkydb",
					Guid:  "murkydb-guid",
				},
			}

			servicePlans := []models.ServicePlanFields{{
				Name: "spark",
				Guid: "murkydb-spark-guid",
			}, {
				Name: "flare",
				Guid: "murkydb-flare-guid",
			},
			}
			serviceRepo.FindInstanceByNameServiceInstance = serviceInstance
			planBuilder.GetPlansForServiceForOrgReturns(servicePlans, nil)

		})
		It("successfully updates a service", func() {
			callUpdateService([]string{"-p", "flare", "my-service-instance"})

			Expect(ui.Outputs).To(ContainSubstrings(
				[]string{"Updating service", "my-service", "as", "my-user", "..."},
				[]string{"OK"},
			))
			Expect(serviceRepo.FindInstanceByNameName).To(Equal("my-service-instance"))
			serviceGuid, orgName := planBuilder.GetPlansForServiceForOrgArgsForCall(0)
			Expect(serviceGuid).To(Equal("murkydb-guid"))
			Expect(orgName).To(Equal("my-org"))
			Expect(serviceRepo.UpdateServiceInstanceArgs.InstanceGuid).To(Equal("my-service-instance-guid"))
			Expect(serviceRepo.UpdateServiceInstanceArgs.PlanGuid).To(Equal("murkydb-flare-guid"))
		})

		Context("when there is an err finding the instance", func() {
			It("returns an error", func() {
				serviceRepo.FindInstanceByNameErr = true

				callUpdateService([]string{"-p", "flare", "some-stupid-not-real-instance"})

				Expect(ui.Outputs).To(ContainSubstrings(
					[]string{"Error finding instance"},
					[]string{"FAILED"},
				))
			})
		})
		Context("when there is an err finding service plans", func() {
			It("returns an error", func() {
				planBuilder.GetPlansForServiceForOrgReturns(nil, errors.New("Error fetching plans"))

				callUpdateService([]string{"-p", "flare", "some-stupid-not-real-instance"})

				Expect(ui.Outputs).To(ContainSubstrings(
					[]string{"Error fetching plans"},
					[]string{"FAILED"},
				))
			})
		})
		Context("when the plan specified does not exist in the service offering", func() {
			It("returns an error", func() {
				callUpdateService([]string{"-p", "not-a-real-plan", "instance-without-service-offering"})

				Expect(ui.Outputs).To(ContainSubstrings(
					[]string{"Plan does not exist for the murkydb service"},
					[]string{"FAILED"},
				))
			})
		})
		Context("when there is an error updating the service instance", func() {
			It("returns an error", func() {
				serviceRepo.UpdateServiceInstanceReturnsErr = true
				callUpdateService([]string{"-p", "flare", "my-service-instance"})

				Expect(ui.Outputs).To(ContainSubstrings(
					[]string{"Error updating service instance"},
					[]string{"FAILED"},
				))
			})
		})
	})
})
<|endoftext|>


<commit_before>package main

import (
	"context"
	"flag"
	"path"
	"strings"

	"go.skia.org/infra/go/gerrit"
	"go.skia.org/infra/task_driver/go/lib/checkout"
	"go.skia.org/infra/task_driver/go/lib/gerrit_steps"
	"go.skia.org/infra/task_driver/go/lib/golang"
	"go.skia.org/infra/task_driver/go/lib/os_steps"
	"go.skia.org/infra/task_driver/go/td"
)

var (
	// Required properties for this task.
	gerritProject = flag.String("gerrit_project", "", "Gerrit project name.")
	gerritUrl     = flag.String("gerrit_url", "", "URL of the Gerrit server.")
	projectId     = flag.String("project_id", "", "ID of the Google Cloud project.")
	reviewers     = flag.String("reviewers", "", "Comma-separated list of emails to review the CL.")
	taskId        = flag.String("task_id", "", "ID of this task.")
	taskName      = flag.String("task_name", "", "Name of the task.")
	workdir       = flag.String("workdir", ".", "Working directory")

	checkoutFlags = checkout.SetupFlags(nil)

	// Optional flags.
	local  = flag.Bool("local", false, "True if running locally (as opposed to on the bots)")
	output = flag.String("o", "", "If provided, dump a JSON blob of step data to the given file. Prints to stdout if '-' is given.")
)

func main() {
	// Setup.
	ctx := td.StartRun(projectId, taskId, taskName, output, local)
	defer td.EndRun(ctx)

	rs, err := checkout.GetRepoState(checkoutFlags)
	if err != nil {
		td.Fatal(ctx, err)
	}
	if *gerritProject == "" {
		td.Fatalf(ctx, "--gerrit_project is required.")
	}
	if *gerritUrl == "" {
		td.Fatalf(ctx, "--gerrit_url is required.")
	}

	wd, err := os_steps.Abs(ctx, *workdir)
	if err != nil {
		td.Fatal(ctx, err)
	}

	// Check out the code.
	co, err := checkout.EnsureGitCheckout(ctx, path.Join(wd, "repo"), rs)
	if err != nil {
		td.Fatal(ctx, err)
	}

	// Setup go.
	ctx = golang.WithEnv(ctx, wd)

	// Perform steps to update the dependencies.
	// By default, the Go env includes GOFLAGS=-mod=readonly, which prevents
	// commands from modifying go.mod; in this case, we want to modify it,
	// so unset that variable.
	ctx = td.WithEnv(ctx, []string{"GOFLAGS="})
	if _, err := golang.Go(ctx, co.Dir(), "get", "-u"); err != nil {
		td.Fatal(ctx, err)
	}

	// Install some tool dependencies.
	if err := golang.InstallCommonDeps(ctx, co.Dir()); err != nil {
		td.Fatal(ctx, err)
	}

	// These commands may also update dependencies, or their results may
	// change based on the updated dependencies.
	if _, err := golang.Go(ctx, co.Dir(), "build", "./..."); err != nil {
		td.Fatal(ctx, err)
	}
	// Setting -exec=echo causes the tests to not actually run; therefore
	// this compiles the tests but doesn't run them.
	if _, err := golang.Go(ctx, co.Dir(), "test", "-exec=echo", "./..."); err != nil {
		td.Fatal(ctx, err)
	}
	if _, err := golang.Go(ctx, co.Dir(), "generate", "./..."); err != nil {
		td.Fatal(ctx, err)
	}

	// If we changed anything, upload a CL.
	diff, err := co.Git(ctx, "diff", "--name-only")
	if err != nil {
		td.Fatal(ctx, err)
	}
	diff = strings.TrimSpace(diff)
	modFiles := strings.Split(diff, "\n")
	if len(modFiles) > 0 {
		g, err := gerrit_steps.Init(ctx, *local, wd, *gerritUrl)
		if err != nil {
			td.Fatal(ctx, err)
		}
		if err := td.Do(ctx, td.Props("Upload CL").Infra(), func(ctx context.Context) error {
			ci, err := gerrit.CreateAndEditChange(ctx, g, *gerritProject, "master", "Update Go deps", rs.Revision, func(ctx context.Context, g gerrit.GerritInterface, ci *gerrit.ChangeInfo) error {
				for _, f := range modFiles {
					contents, err := os_steps.ReadFile(ctx, path.Join(co.Dir(), f))
					if err != nil {
						return err
					}
					if err := g.EditFile(ctx, ci, f, string(contents)); err != nil {
						return err
					}
				}
				return nil
			})
			if err != nil {
				return err
			}
			var labels map[string]interface{}
			if !*local && rs.Issue == "" {
				labels = map[string]interface{}{
					gerrit.CODEREVIEW_LABEL:  gerrit.CODEREVIEW_LABEL_APPROVE,
					gerrit.COMMITQUEUE_LABEL: gerrit.COMMITQUEUE_LABEL_SUBMIT,
				}
			}
			if err := g.SetReview(ctx, ci, "Ready for review.", labels, strings.Split(*reviewers, ",")); err != nil {
				return err
			}
			return nil
		}); err != nil {
			td.Fatal(ctx, err)
		}
	}
}
<commit_msg>Fix update_go_deps when there are no modified files<commit_after>package main

import (
	"context"
	"flag"
	"path"
	"strings"

	"go.skia.org/infra/go/gerrit"
	"go.skia.org/infra/task_driver/go/lib/checkout"
	"go.skia.org/infra/task_driver/go/lib/gerrit_steps"
	"go.skia.org/infra/task_driver/go/lib/golang"
	"go.skia.org/infra/task_driver/go/lib/os_steps"
	"go.skia.org/infra/task_driver/go/td"
)

var (
	// Required properties for this task.
	gerritProject = flag.String("gerrit_project", "", "Gerrit project name.")
	gerritUrl     = flag.String("gerrit_url", "", "URL of the Gerrit server.")
	projectId     = flag.String("project_id", "", "ID of the Google Cloud project.")
	reviewers     = flag.String("reviewers", "", "Comma-separated list of emails to review the CL.")
	taskId        = flag.String("task_id", "", "ID of this task.")
	taskName      = flag.String("task_name", "", "Name of the task.")
	workdir       = flag.String("workdir", ".", "Working directory")

	checkoutFlags = checkout.SetupFlags(nil)

	// Optional flags.
	local  = flag.Bool("local", false, "True if running locally (as opposed to on the bots)")
	output = flag.String("o", "", "If provided, dump a JSON blob of step data to the given file. Prints to stdout if '-' is given.")
)

func main() {
	// Setup.
	ctx := td.StartRun(projectId, taskId, taskName, output, local)
	defer td.EndRun(ctx)

	rs, err := checkout.GetRepoState(checkoutFlags)
	if err != nil {
		td.Fatal(ctx, err)
	}
	if *gerritProject == "" {
		td.Fatalf(ctx, "--gerrit_project is required.")
	}
	if *gerritUrl == "" {
		td.Fatalf(ctx, "--gerrit_url is required.")
	}

	wd, err := os_steps.Abs(ctx, *workdir)
	if err != nil {
		td.Fatal(ctx, err)
	}

	// Check out the code.
	co, err := checkout.EnsureGitCheckout(ctx, path.Join(wd, "repo"), rs)
	if err != nil {
		td.Fatal(ctx, err)
	}

	// Setup go.
	ctx = golang.WithEnv(ctx, wd)

	// Perform steps to update the dependencies.
	// By default, the Go env includes GOFLAGS=-mod=readonly, which prevents
	// commands from modifying go.mod; in this case, we want to modify it,
	// so unset that variable.
	ctx = td.WithEnv(ctx, []string{"GOFLAGS="})
	if _, err := golang.Go(ctx, co.Dir(), "get", "-u"); err != nil {
		td.Fatal(ctx, err)
	}

	// Install some tool dependencies.
	if err := golang.InstallCommonDeps(ctx, co.Dir()); err != nil {
		td.Fatal(ctx, err)
	}

	// These commands may also update dependencies, or their results may
	// change based on the updated dependencies.
	if _, err := golang.Go(ctx, co.Dir(), "build", "./..."); err != nil {
		td.Fatal(ctx, err)
	}
	// Setting -exec=echo causes the tests to not actually run; therefore
	// this compiles the tests but doesn't run them.
	if _, err := golang.Go(ctx, co.Dir(), "test", "-exec=echo", "./..."); err != nil {
		td.Fatal(ctx, err)
	}
	if _, err := golang.Go(ctx, co.Dir(), "generate", "./..."); err != nil {
		td.Fatal(ctx, err)
	}

	// If we changed anything, upload a CL.
	diff, err := co.Git(ctx, "diff", "--name-only")
	if err != nil {
		td.Fatal(ctx, err)
	}
	diff = strings.TrimSpace(diff)
	modFiles := strings.Split(diff, "\n")
	if len(modFiles) > 0 && diff != "" {
		g, err := gerrit_steps.Init(ctx, *local, wd, *gerritUrl)
		if err != nil {
			td.Fatal(ctx, err)
		}
		if err := td.Do(ctx, td.Props("Upload CL").Infra(), func(ctx context.Context) error {
			ci, err := gerrit.CreateAndEditChange(ctx, g, *gerritProject, "master", "Update Go deps", rs.Revision, func(ctx context.Context, g gerrit.GerritInterface, ci *gerrit.ChangeInfo) error {
				for _, f := range modFiles {
					contents, err := os_steps.ReadFile(ctx, path.Join(co.Dir(), f))
					if err != nil {
						return err
					}
					if err := g.EditFile(ctx, ci, f, string(contents)); err != nil {
						return err
					}
				}
				return nil
			})
			if err != nil {
				return err
			}
			var labels map[string]interface{}
			if !*local && rs.Issue == "" {
				labels = map[string]interface{}{
					gerrit.CODEREVIEW_LABEL:  gerrit.CODEREVIEW_LABEL_APPROVE,
					gerrit.COMMITQUEUE_LABEL: gerrit.COMMITQUEUE_LABEL_SUBMIT,
				}
			}
			if err := g.SetReview(ctx, ci, "Ready for review.", labels, strings.Split(*reviewers, ",")); err != nil {
				return err
			}
			return nil
		}); err != nil {
			td.Fatal(ctx, err)
		}
	}
}
<|endoftext|>


<commit_before>/*
Copyright IBM Corp. 2016 All Rights Reserved.

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

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

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

package main

import (
	"context"
	"flag"
	"fmt"

	"google.golang.org/grpc"

	genesisconfig "github.com/hyperledger/fabric/common/configtx/tool/localconfig"
	"github.com/hyperledger/fabric/msp"
	mspmgmt "github.com/hyperledger/fabric/msp/mgmt"
	"github.com/hyperledger/fabric/orderer/localconfig"
	cb "github.com/hyperledger/fabric/protos/common"
	ab "github.com/hyperledger/fabric/protos/orderer"
)

var conf *config.TopLevel
var genConf *genesisconfig.Profile
var signer msp.SigningIdentity

type broadcastClient struct {
	ab.AtomicBroadcast_BroadcastClient
}

func (bc *broadcastClient) broadcast(env *cb.Envelope) error {
	var err error
	var resp *ab.BroadcastResponse

	err = bc.Send(env)
	if err != nil {
		return err
	}

	resp, err = bc.Recv()
	if err != nil {
		return err
	}

	fmt.Println("Status:", resp)
	return nil
}

// cmdImpl holds the command and its arguments.
type cmdImpl struct {
	name string
	args argsImpl
}

// argsImpl holds all the possible arguments for all possible commands.
type argsImpl struct {
	consensusType  string
	creationPolicy string
	chainID        string
}

func init() {
	conf = config.Load()
	genConf = genesisconfig.Load(genesisconfig.SampleInsecureProfile)

	// Load local MSP
	err := mspmgmt.LoadLocalMsp(conf.General.LocalMSPDir, conf.General.BCCSP, conf.General.LocalMSPID)
	if err != nil {
		panic(fmt.Errorf("Failed to initialize local MSP: %s", err))
	}

	msp := mspmgmt.GetLocalMSP()
	signer, err = msp.GetDefaultSigningIdentity()
	if err != nil {
		panic(fmt.Errorf("Failed to initialize get default signer: %s", err))
	}
}

func main() {
	cmd := new(cmdImpl)
	var srv string

	flag.StringVar(&srv, "server", fmt.Sprintf("%s:%d", conf.General.ListenAddress, conf.General.ListenPort), "The RPC server to connect to.")
	flag.StringVar(&cmd.name, "cmd", "newChain", "The action that this client is requesting via the config transaction.")
	flag.StringVar(&cmd.args.consensusType, "consensusType", genConf.Orderer.OrdererType, "In case of a newChain command, the type of consensus the ordering service is running on.")
	flag.StringVar(&cmd.args.creationPolicy, "creationPolicy", "AcceptAllPolicy", "In case of a newChain command, the chain creation policy this request should be validated against.")
	flag.StringVar(&cmd.args.chainID, "chainID", "NewChannelId", "In case of a newChain command, the chain ID to create.")
	flag.Parse()

	conn, err := grpc.Dial(srv, grpc.WithInsecure())
	defer func() {
		_ = conn.Close()
	}()
	if err != nil {
		fmt.Println("Error connecting:", err)
		return
	}

	client, err := ab.NewAtomicBroadcastClient(conn).Broadcast(context.TODO())
	if err != nil {
		fmt.Println("Error connecting:", err)
		return
	}

	bc := &broadcastClient{client}

	switch cmd.name {
	case "newChain":
		env := newChainRequest(cmd.args.consensusType, cmd.args.creationPolicy, cmd.args.chainID)
		fmt.Println("Requesting the creation of chain", cmd.args.chainID)
		fmt.Println(bc.broadcast(env))
	default:
		panic("Invalid command given")
	}
}
<commit_msg>[FAB-6047] Modify the default channel name<commit_after>/*
Copyright IBM Corp. 2016 All Rights Reserved.

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

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

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

package main

import (
	"context"
	"flag"
	"fmt"

	"google.golang.org/grpc"

	genesisconfig "github.com/hyperledger/fabric/common/configtx/tool/localconfig"
	"github.com/hyperledger/fabric/msp"
	mspmgmt "github.com/hyperledger/fabric/msp/mgmt"
	"github.com/hyperledger/fabric/orderer/localconfig"
	cb "github.com/hyperledger/fabric/protos/common"
	ab "github.com/hyperledger/fabric/protos/orderer"
)

var conf *config.TopLevel
var genConf *genesisconfig.Profile
var signer msp.SigningIdentity

type broadcastClient struct {
	ab.AtomicBroadcast_BroadcastClient
}

func (bc *broadcastClient) broadcast(env *cb.Envelope) error {
	var err error
	var resp *ab.BroadcastResponse

	err = bc.Send(env)
	if err != nil {
		return err
	}

	resp, err = bc.Recv()
	if err != nil {
		return err
	}

	fmt.Println("Status:", resp)
	return nil
}

// cmdImpl holds the command and its arguments.
type cmdImpl struct {
	name string
	args argsImpl
}

// argsImpl holds all the possible arguments for all possible commands.
type argsImpl struct {
	consensusType  string
	creationPolicy string
	chainID        string
}

func init() {
	conf = config.Load()
	genConf = genesisconfig.Load(genesisconfig.SampleInsecureProfile)

	// Load local MSP
	err := mspmgmt.LoadLocalMsp(conf.General.LocalMSPDir, conf.General.BCCSP, conf.General.LocalMSPID)
	if err != nil {
		panic(fmt.Errorf("Failed to initialize local MSP: %s", err))
	}

	msp := mspmgmt.GetLocalMSP()
	signer, err = msp.GetDefaultSigningIdentity()
	if err != nil {
		panic(fmt.Errorf("Failed to initialize get default signer: %s", err))
	}
}

func main() {
	cmd := new(cmdImpl)
	var srv string

	flag.StringVar(&srv, "server", fmt.Sprintf("%s:%d", conf.General.ListenAddress, conf.General.ListenPort), "The RPC server to connect to.")
	flag.StringVar(&cmd.name, "cmd", "newChain", "The action that this client is requesting via the config transaction.")
	flag.StringVar(&cmd.args.consensusType, "consensusType", genConf.Orderer.OrdererType, "In case of a newChain command, the type of consensus the ordering service is running on.")
	flag.StringVar(&cmd.args.creationPolicy, "creationPolicy", "AcceptAllPolicy", "In case of a newChain command, the chain creation policy this request should be validated against.")
	flag.StringVar(&cmd.args.chainID, "chainID", "mychannel", "In case of a newChain command, the chain ID to create.")
	flag.Parse()

	conn, err := grpc.Dial(srv, grpc.WithInsecure())
	defer func() {
		_ = conn.Close()
	}()
	if err != nil {
		fmt.Println("Error connecting:", err)
		return
	}

	client, err := ab.NewAtomicBroadcastClient(conn).Broadcast(context.TODO())
	if err != nil {
		fmt.Println("Error connecting:", err)
		return
	}

	bc := &broadcastClient{client}

	switch cmd.name {
	case "newChain":
		env := newChainRequest(cmd.args.consensusType, cmd.args.creationPolicy, cmd.args.chainID)
		fmt.Println("Requesting the creation of chain", cmd.args.chainID)
		fmt.Println(bc.broadcast(env))
	default:
		panic("Invalid command given")
	}
}
<|endoftext|>


<commit_before>package tau

import (
	"log"
	"testing"
	"time"
)

type TestTime struct {
	time.Time
	current time.Time
}

func (t TestTime) Since() Tau {
	return Tau(t.current.Sub(t.Time) / 1e9)
}

// newTestTime creates a deterministic TestTime for given value and current time.
func newTestTime(current, value string) TestTime {
	layout := "2006-01-02 15:04" // a simple time layout
	parse := func(s string) time.Time {
		t, err := time.Parse(layout, s)
		if err != nil {
			log.Fatalf("got err: %v\n", err)
		}
		return t

	}
	return TestTime{
		Time:    parse(value),
		current: parse(current),
	}
}

func TestTau(t *testing.T) {
	cases := []struct {
		in   Time
		want Tau
	}{
		{
			in:   newTestTime("2015-06-29 12:00", "2015-06-29 12:00"),
			want: Tau(0),
		},
		{
			in:   newTestTime("2015-06-29 12:00", "2015-06-17 22:14"),
			want: Tau(999960),
		},
		{
			in:   newTestTime("2015-06-29 12:00", "2015-06-17 22:13"),
			want: Tau(1000020),
		},
		{
			in:   newTestTime("2016-11-26 16:47", "1985-03-20 15:00"),
			want: Tau(1000000020),
		},
		{
			in:   newTestTime("2019-03-10 18:34", "1955-10-24 15:00"),
			want: Tau(2000000040),
		},
	}

	for i, tt := range cases {
		out := TauSince(tt.in)
		if tt.want != out {
			t.Errorf("[%d] TauSince(%v) => %v; want %v\n", i, tt.in, out, tt.want)
		}
	}

}

func TestMegaTau(t *testing.T) {
	cases := []struct {
		in   Time
		want MegaTau
	}{
		{
			in:   newTestTime("2015-06-29 12:00", "2015-06-29 12:00"),
			want: MegaTau(0),
		},
		{
			in:   newTestTime("2015-06-29 12:00", "2015-06-17 22:14"),
			want: MegaTau(0),
		},
		{
			in:   newTestTime("2015-06-29 12:00", "2015-06-17 22:13"),
			want: MegaTau(1),
		},
		{
			in:   newTestTime("2016-11-26 16:46", "1985-03-20 15:00"),
			want: MegaTau(999),
		},
		{
			in:   newTestTime("2015-05-09 09:00", "1985-03-20 15:00"),
			want: MegaTau(950),
		},
		{
			in:   newTestTime("2016-11-26 16:47", "1985-03-20 15:00"),
			want: MegaTau(1000),
		},
		{
			in:   newTestTime("2018-06-30 12:00", "1985-03-20 15:00"),
			want: MegaTau(1050),
		},
		{
			in:   newTestTime("2014-12-03 17:47", "1983-03-27 15:00"),
			want: MegaTau(1000),
		},
		{
			in:   newTestTime("2015-06-26 15:00", "1983-03-27 15:00"),
			want: MegaTau(1017),
		},
		{
			in:   newTestTime("2015-06-26 15:00", "1985-03-20 15:00"),
			want: MegaTau(955),
		},
		{
			// TODO(hkjn): This is the largest time span that can be
			// represented with time.Duration. Add more test cases once this
			// limitation is removed.
			in:   newTestTime("2277-06-25 07:26", "1985-03-20 15:00"),
			want: MegaTau(9222),
		},
	}
	for i, tt := range cases {
		out := TauSince(tt.in).Mega()
		if tt.want != out {
			t.Errorf("[%d] TauSince(%v).Mega() => %v; want %v\n", i, tt.in, out, tt.want)
		}
	}
}

func TestGigaTau(t *testing.T) {
	cases := []struct {
		in   Time
		want GigaTau
	}{
		{
			in:   newTestTime("2015-06-29 12:00", "2015-06-29 12:00"),
			want: GigaTau(0),
		},
		{
			in:   newTestTime("2016-11-26 16:46", "1985-03-20 15:00"),
			want: GigaTau(0),
		},
		{
			in:   newTestTime("2016-11-26 16:47", "1985-03-20 15:00"),
			want: GigaTau(1),
		},
		{
			in:   newTestTime("2019-03-10 18:34", "1955-10-24 15:00"),
			want: GigaTau(2),
		},
		{
			in:   newTestTime("2277-06-25 07:26", "1985-03-20 15:00"),
			want: GigaTau(9),
		},
	}
	for i, tt := range cases {
		out := TauSince(tt.in).Giga()
		if tt.want != out {
			t.Errorf("[%d] TauSince(%v).Giga() => %v; want %v\n", i, tt.in, out, tt.want)
		}
	}
}
<commit_msg>Add test cases<commit_after>package tau

import (
	"log"
	"testing"
	"time"
)

type TestTime struct {
	time.Time
	current time.Time
}

func (t TestTime) Since() Tau {
	return Tau(t.current.Sub(t.Time) / 1e9)
}

// newTestTime creates a deterministic TestTime for given value and current time.
func newTestTime(current, value string) TestTime {
	layout := "2006-01-02 15:04" // a simple time layout
	parse := func(s string) time.Time {
		t, err := time.Parse(layout, s)
		if err != nil {
			log.Fatalf("got err: %v\n", err)
		}
		return t

	}
	return TestTime{
		Time:    parse(value),
		current: parse(current),
	}
}

func TestTau(t *testing.T) {
	cases := []struct {
		in   Time
		want Tau
	}{
		{
			in:   newTestTime("2015-06-29 12:00", "2015-06-29 12:00"),
			want: Tau(0),
		},
		{
			in:   newTestTime("2015-06-29 12:00", "2015-06-17 22:14"),
			want: Tau(999960),
		},
		{
			in:   newTestTime("2015-06-29 12:00", "2015-06-17 22:13"),
			want: Tau(1000020),
		},
		{
			in:   newTestTime("2016-11-26 16:47", "1985-03-20 15:00"),
			want: Tau(1000000020),
		},
		{
			in:   newTestTime("2019-03-10 18:34", "1955-10-24 15:00"),
			want: Tau(2000000040),
		},
	}

	for i, tt := range cases {
		out := TauSince(tt.in)
		if tt.want != out {
			t.Errorf("[%d] TauSince(%v) => %v; want %v\n", i, tt.in, out, tt.want)
		}
	}

}

func TestMegaTau(t *testing.T) {
	cases := []struct {
		in   Time
		want MegaTau
	}{
		{
			in:   newTestTime("2015-06-29 12:00", "2015-06-29 12:00"),
			want: MegaTau(0),
		},
		{
			in:   newTestTime("2015-06-29 12:00", "2015-06-17 22:14"),
			want: MegaTau(0),
		},
		{
			in:   newTestTime("2015-06-29 12:00", "2015-06-17 22:13"),
			want: MegaTau(1),
		},
		{
			in:   newTestTime("2016-11-26 16:46", "1985-03-20 15:00"),
			want: MegaTau(999),
		},
		{
			in:   newTestTime("2015-05-09 09:00", "1985-03-20 15:00"),
			want: MegaTau(950),
		},
		{
			in:   newTestTime("2016-11-26 16:47", "1985-03-20 15:00"),
			want: MegaTau(1000),
		},
		{
			in:   newTestTime("2018-06-30 12:00", "1985-03-20 15:00"),
			want: MegaTau(1050),
		},
		{
			in:   newTestTime("2014-12-03 17:47", "1983-03-27 15:00"),
			want: MegaTau(1000),
		},
		{
			in:   newTestTime("2016-07-04 12:00", "1983-03-27 15:00"),
			want: MegaTau(1050),
		},
		{
			in:   newTestTime("2018-02-03 12:00", "1983-03-27 15:00"),
			want: MegaTau(1100),
		},
		{
			in:   newTestTime("2015-06-26 15:00", "1985-03-20 15:00"),
			want: MegaTau(955),
		},
		{
			// TODO(hkjn): This is the largest time span that can be
			// represented with time.Duration. Add more test cases once this
			// limitation is removed.
			in:   newTestTime("2277-06-25 07:26", "1985-03-20 15:00"),
			want: MegaTau(9222),
		},
	}
	for i, tt := range cases {
		out := TauSince(tt.in).Mega()
		if tt.want != out {
			t.Errorf("[%d] TauSince(%v).Mega() => %v; want %v\n", i, tt.in, out, tt.want)
		}
	}
}

func TestGigaTau(t *testing.T) {
	cases := []struct {
		in   Time
		want GigaTau
	}{
		{
			in:   newTestTime("2015-06-29 12:00", "2015-06-29 12:00"),
			want: GigaTau(0),
		},
		{
			in:   newTestTime("2016-11-26 16:46", "1985-03-20 15:00"),
			want: GigaTau(0),
		},
		{
			in:   newTestTime("2016-11-26 16:47", "1985-03-20 15:00"),
			want: GigaTau(1),
		},
		{
			in:   newTestTime("2019-03-10 18:34", "1955-10-24 15:00"),
			want: GigaTau(2),
		},
		{
			in:   newTestTime("2277-06-25 07:26", "1985-03-20 15:00"),
			want: GigaTau(9),
		},
	}
	for i, tt := range cases {
		out := TauSince(tt.in).Giga()
		if tt.want != out {
			t.Errorf("[%d] TauSince(%v).Giga() => %v; want %v\n", i, tt.in, out, tt.want)
		}
	}
}
<|endoftext|>


<commit_before>// Copyright (C) 2017. See 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.

// +build linux darwin
// +build !windows

package openssl

/*
#include <errno.h>
#include <openssl/crypto.h>
#include <pthread.h>

pthread_mutex_t* goopenssl_locks;

int go_init_locks() {
	int rc = 0;
	int nlock;
	int i;
	int locks_needed = CRYPTO_num_locks();

	goopenssl_locks = (pthread_mutex_t*)malloc(
		sizeof(pthread_mutex_t) * locks_needed);
	if (!goopenssl_locks) {
		return ENOMEM;
	}
	for (nlock = 0; nlock < locks_needed; ++nlock) {
		rc = pthread_mutex_init(&goopenssl_locks[nlock], NULL);
		if (rc != 0) {
			break;
		}
	}

	if (rc != 0) {
		for (i = nlock - 1; i >= 0; --i) {
			pthread_mutex_destroy(&goopenssl_locks[i]);
		}
		free(goopenssl_locks);
		goopenssl_locks = NULL;
	}
	return rc;
}

void go_thread_locking_callback(int mode, int n, const char *file,
	int line) {
	if (mode & CRYPTO_LOCK) {
		pthread_mutex_lock(&goopenssl_locks[n]);
	} else {
		pthread_mutex_unlock(&goopenssl_locks[n]);
	}
}
*/
import "C"
<commit_msg>Fix build on solarish platforms<commit_after>// Copyright (C) 2017. See 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.

// +build linux darwin solaris
// +build !windows

package openssl

/*
#include <errno.h>
#include <openssl/crypto.h>
#include <pthread.h>

pthread_mutex_t* goopenssl_locks;

int go_init_locks() {
	int rc = 0;
	int nlock;
	int i;
	int locks_needed = CRYPTO_num_locks();

	goopenssl_locks = (pthread_mutex_t*)malloc(
		sizeof(pthread_mutex_t) * locks_needed);
	if (!goopenssl_locks) {
		return ENOMEM;
	}
	for (nlock = 0; nlock < locks_needed; ++nlock) {
		rc = pthread_mutex_init(&goopenssl_locks[nlock], NULL);
		if (rc != 0) {
			break;
		}
	}

	if (rc != 0) {
		for (i = nlock - 1; i >= 0; --i) {
			pthread_mutex_destroy(&goopenssl_locks[i]);
		}
		free(goopenssl_locks);
		goopenssl_locks = NULL;
	}
	return rc;
}

void go_thread_locking_callback(int mode, int n, const char *file,
	int line) {
	if (mode & CRYPTO_LOCK) {
		pthread_mutex_lock(&goopenssl_locks[n]);
	} else {
		pthread_mutex_unlock(&goopenssl_locks[n]);
	}
}
*/
import "C"
<|endoftext|>


<commit_before>package sched

import (
    "log"
    "net"
    "time"
    "sync"
    "strings"
    "container/list"
    "container/heap"
)

type Sched struct {
    timer            *time.Timer
    grabQueue        *list.List
    jobQueue         *list.List
    entryPoint       string
    JobLocker        *sync.Mutex
    Funcs            map[string]*FuncStat
    store            Storer
    pq               map[string]*PriorityQueue
}

type Counter uint

func (c *Counter) Incr() {
    *c = *c + 1
}

func (c *Counter) Decr() {
    *c = *c - 1
}

type FuncStat struct {
    Worker     Counter `json:"worker_count"`
    Job        Counter `json:"job_count"`
    Processing Counter `json:"processing"`
}

func NewSched(entryPoint string, store Storer) *Sched {
    sched := new(Sched)
    sched.timer = time.NewTimer(1 * time.Hour)
    sched.grabQueue = list.New()
    sched.jobQueue = list.New()
    sched.entryPoint = entryPoint
    sched.JobLocker = new(sync.Mutex)
    sched.Funcs = make(map[string]*FuncStat)
    sched.store = store
    sched.pq = make(map[string]*PriorityQueue)
    return sched
}

func (sched *Sched) Serve() {
    parts := strings.SplitN(sched.entryPoint, "://", 2)
    if parts[0] == "unix" {
        sockCheck(parts[1])
    }
    sched.checkJobQueue()
    go sched.handle()
    listen, err := net.Listen(parts[0], parts[1])
    if err != nil {
        log.Fatal(err)
    }
    defer listen.Close()
    log.Printf("huabot-sched started on %s\n", sched.entryPoint)
    for {
        conn, err := listen.Accept()
        if err != nil {
            log.Fatal(err)
        }
        sched.HandleConnection(conn)
    }
}

func (sched *Sched) Notify() {
    sched.timer.Reset(time.Millisecond)
}

func (sched *Sched) DieWorker(worker *Worker) {
    defer sched.Notify()
    sched.removeGrabQueue(worker)
    worker.Close()
}

func (sched *Sched) HandleConnection(conn net.Conn) {
    c := Conn{Conn: conn}
    payload, err := c.Receive()
    if err != nil {
        return
    }
    switch payload[0] {
    case TYPE_CLIENT:
        client := NewClient(sched, c)
        go client.Handle()
        break
    case TYPE_WORKER:
        worker := NewWorker(sched, c)
        go worker.Handle()
        break
    default:
        log.Printf("Unsupport client %d\n", payload[0])
        c.Close()
        break
    }
}

func (sched *Sched) Done(jobId int64) {
    defer sched.Notify()
    defer sched.JobLocker.Unlock()
    sched.JobLocker.Lock()
    removeListJob(sched.jobQueue, jobId)
    job, err := sched.store.Get(jobId)
    if err == nil {
        sched.store.Delete(jobId)
        sched.DecrStatJob(job)
        sched.DecrStatProc(job)
    }
    return
}

func (sched *Sched) isDoJob(job Job) bool {
    now := time.Now()
    current := int64(now.Unix())
    ret := false
    for e := sched.jobQueue.Front(); e != nil; e = e.Next() {
        chk := e.Value.(Job)
        runAt := chk.RunAt
        if runAt < chk.SchedAt {
            runAt = chk.SchedAt
        }
        if chk.Timeout > 0 && runAt + chk.Timeout < current {
            newJob, _ := sched.store.Get(chk.Id)
            if newJob.Status == JOB_STATUS_PROC {
                sched.DecrStatProc(newJob)
                newJob.Status = JOB_STATUS_READY
                sched.store.Save(newJob)
                pq := sched.pq[newJob.Func]
                item := &Item{
                    value: newJob.Id,
                    priority: newJob.SchedAt,
                }
                heap.Push(pq, item)
            }
            sched.jobQueue.Remove(e)
            continue
        }
        if chk.Id == job.Id {
            old := e.Value.(Job)
            runAt := old.RunAt
            if runAt < old.SchedAt {
                runAt = old.SchedAt
            }
            if old.Timeout > 0 && runAt + old.Timeout < current {
                ret = false
            } else {
                ret = true
            }
        }
    }
    return ret
}

func (sched *Sched) SubmitJob(worker *Worker, job Job) {
    defer sched.JobLocker.Unlock()
    sched.JobLocker.Lock()
    if job.Name == "" {
        sched.store.Delete(job.Id)
        return
    }
    if sched.isDoJob(job) {
        return
    }
    if !worker.alive {
        return
    }
    if err := worker.HandleDo(job); err != nil {
        worker.alive = false
        go sched.DieWorker(worker)
        return
    }
    now := time.Now()
    current := int64(now.Unix())
    job.Status = JOB_STATUS_PROC
    job.RunAt = current
    sched.store.Save(job)
    sched.IncrStatProc(job)
    sched.jobQueue.PushBack(job)
    sched.removeGrabQueue(worker)
}

func (sched *Sched) handle() {
    var current time.Time
    var timestamp int64
    for {
        if sched.grabQueue.Len() == 0 {
            sched.timer.Reset(time.Minute)
            current =<-sched.timer.C
            continue
        }

        maybeItem := make(map[string]*Item)
        for Func, _ := range sched.Funcs {
            pq, ok := sched.pq[Func]
            if !ok || pq.Len() == 0 {
                continue
            }

            item := heap.Pop(pq).(*Item)

            maybeItem[Func] = item

        }

        if len(maybeItem) == 0 {
            sched.timer.Reset(time.Minute)
            current =<-sched.timer.C
        }

        var lessItem *Item
        var lessFunc string

        for Func, item := range maybeItem {
            if lessItem == nil {
                lessItem = item
                lessFunc = Func
                continue
            }
            if lessItem.priority > item.priority {
                lessItem = item
                lessFunc = Func
            }
        }

        for Func, item := range maybeItem {
            if Func == lessFunc {
                continue
            }
            pq := sched.pq[Func]
            heap.Push(pq, item)
        }

        schedJob, err := sched.store.Get(lessItem.value)

        if err != nil {
            continue
        }

        pq := sched.pq[schedJob.Func]
        timestamp = int64(time.Now().Unix())

        if schedJob.SchedAt > timestamp {
            sched.timer.Reset(time.Second * time.Duration(schedJob.SchedAt - timestamp))
            current =<-sched.timer.C
            timestamp = int64(current.Unix())
            if schedJob.SchedAt > timestamp {
                heap.Push(pq, lessItem)
                continue
            }
        }

        isSubmited := false
        for e := sched.grabQueue.Front(); e != nil; e = e.Next() {
            worker := e.Value.(*Worker)
            for _, Func := range worker.Funcs {
                if schedJob.Func == Func {
                    sched.SubmitJob(worker, schedJob)
                    isSubmited = true
                    break
                }
            }
            if isSubmited {
                break
            }
        }

        if !isSubmited {
            sched.DecrStatFunc(schedJob.Func)
        }
    }
}

func (sched *Sched) Fail(jobId int64) {
    defer sched.Notify()
    defer sched.JobLocker.Unlock()
    sched.JobLocker.Lock()
    removeListJob(sched.jobQueue, jobId)
    job, _ := sched.store.Get(jobId)
    sched.DecrStatProc(job)
    job.Status = JOB_STATUS_READY
    sched.store.Save(job)
    pq := sched.pq[job.Func]
    item := &Item{
        value: job.Id,
        priority: job.SchedAt,
    }
    heap.Push(pq, item)
    return
}

func (sched *Sched) IncrStatFunc(Func string) {
    stat, ok := sched.Funcs[Func]
    if !ok {
        stat = new(FuncStat)
        sched.Funcs[Func] = stat
    }
    stat.Worker.Incr()
}

func (sched *Sched) DecrStatFunc(Func string) {
    stat, ok := sched.Funcs[Func]
    if ok {
        stat.Worker.Decr()
    }
}

func (sched *Sched) IncrStatJob(job Job) {
    stat, ok := sched.Funcs[job.Func]
    if !ok {
        stat = new(FuncStat)
        sched.Funcs[job.Func] = stat
    }
    stat.Job.Incr()
}

func (sched *Sched) DecrStatJob(job Job) {
    stat, ok := sched.Funcs[job.Func]
    if ok {
        stat.Job.Decr()
    }
}

func (sched *Sched) IncrStatProc(job Job) {
    stat, ok := sched.Funcs[job.Func]
    if !ok {
        stat = new(FuncStat)
        sched.Funcs[job.Func] = stat
    }
    if job.Status == JOB_STATUS_PROC {
        stat.Processing.Incr()
    }
}

func (sched *Sched) DecrStatProc(job Job) {
    stat, ok := sched.Funcs[job.Func]
    if ok && job.Status == JOB_STATUS_PROC {
        stat.Processing.Decr()
    }
}

func (sched *Sched) SchedLater(jobId int64, delay int64) {
    defer sched.Notify()
    defer sched.JobLocker.Unlock()
    sched.JobLocker.Lock()
    removeListJob(sched.jobQueue, jobId)
    job, _ := sched.store.Get(jobId)
    sched.DecrStatProc(job)
    job.Status = JOB_STATUS_READY
    var now = time.Now()
    job.SchedAt = int64(now.Unix()) + delay
    sched.store.Save(job)
    pq := sched.pq[job.Func]
    item := &Item{
        value: job.Id,
        priority: job.SchedAt,
    }
    heap.Push(pq, item)
    return
}

func (sched *Sched) removeGrabQueue(worker *Worker) {
    for e := sched.grabQueue.Front(); e != nil; e = e.Next() {
        if e.Value.(*Worker) == worker {
            sched.grabQueue.Remove(e)
        }
    }
}

func (sched *Sched) checkJobQueue() {
    updateQueue := make([]Job, 0)
    removeQueue := make([]Job, 0)
    var now = time.Now()
    current := int64(now.Unix())

    iter := sched.store.NewIterator(nil, nil)
    for {
        if !iter.Next() {
            break
        }
        job := iter.Value()
        if job.Name == "" {
            removeQueue = append(removeQueue, job)
            continue
        }
        sched.IncrStatJob(job)
        if job.Status != JOB_STATUS_PROC {
            pq, ok := sched.pq[job.Func]
            if !ok {
                *pq = make(PriorityQueue, 0)
                sched.pq[job.Func] = pq
                heap.Init(pq)
            }
            item := &Item{
                value: job.Id,
                priority: job.SchedAt,
            }
            heap.Push(pq, item)
            continue
        }
        runAt := job.RunAt
        if runAt < job.SchedAt {
            runAt = job.SchedAt
        }
        if runAt + job.Timeout < current {
            updateQueue = append(updateQueue, job)
        } else {
            sched.jobQueue.PushBack(job)
            sched.IncrStatProc(job)
        }
    }

    iter.Close()

    for _, job := range updateQueue {
        job.Status = JOB_STATUS_READY
        sched.store.Save(job)
    }

    for _, job := range removeQueue {
        sched.store.Delete(job.Id)
    }
}

func (sched *Sched) Close() {
}
<commit_msg>Fix. crash<commit_after>package sched

import (
    "log"
    "net"
    "time"
    "sync"
    "strings"
    "container/list"
    "container/heap"
)

type Sched struct {
    timer            *time.Timer
    grabQueue        *list.List
    jobQueue         *list.List
    entryPoint       string
    JobLocker        *sync.Mutex
    Funcs            map[string]*FuncStat
    store            Storer
    pq               map[string]*PriorityQueue
}

type Counter uint

func (c *Counter) Incr() {
    *c = *c + 1
}

func (c *Counter) Decr() {
    *c = *c - 1
}

type FuncStat struct {
    Worker     Counter `json:"worker_count"`
    Job        Counter `json:"job_count"`
    Processing Counter `json:"processing"`
}

func NewSched(entryPoint string, store Storer) *Sched {
    sched := new(Sched)
    sched.timer = time.NewTimer(1 * time.Hour)
    sched.grabQueue = list.New()
    sched.jobQueue = list.New()
    sched.entryPoint = entryPoint
    sched.JobLocker = new(sync.Mutex)
    sched.Funcs = make(map[string]*FuncStat)
    sched.store = store
    sched.pq = make(map[string]*PriorityQueue)
    return sched
}

func (sched *Sched) Serve() {
    parts := strings.SplitN(sched.entryPoint, "://", 2)
    if parts[0] == "unix" {
        sockCheck(parts[1])
    }
    sched.checkJobQueue()
    go sched.handle()
    listen, err := net.Listen(parts[0], parts[1])
    if err != nil {
        log.Fatal(err)
    }
    defer listen.Close()
    log.Printf("huabot-sched started on %s\n", sched.entryPoint)
    for {
        conn, err := listen.Accept()
        if err != nil {
            log.Fatal(err)
        }
        sched.HandleConnection(conn)
    }
}

func (sched *Sched) Notify() {
    sched.timer.Reset(time.Millisecond)
}

func (sched *Sched) DieWorker(worker *Worker) {
    defer sched.Notify()
    sched.removeGrabQueue(worker)
    worker.Close()
}

func (sched *Sched) HandleConnection(conn net.Conn) {
    c := Conn{Conn: conn}
    payload, err := c.Receive()
    if err != nil {
        return
    }
    switch payload[0] {
    case TYPE_CLIENT:
        client := NewClient(sched, c)
        go client.Handle()
        break
    case TYPE_WORKER:
        worker := NewWorker(sched, c)
        go worker.Handle()
        break
    default:
        log.Printf("Unsupport client %d\n", payload[0])
        c.Close()
        break
    }
}

func (sched *Sched) Done(jobId int64) {
    defer sched.Notify()
    defer sched.JobLocker.Unlock()
    sched.JobLocker.Lock()
    removeListJob(sched.jobQueue, jobId)
    job, err := sched.store.Get(jobId)
    if err == nil {
        sched.store.Delete(jobId)
        sched.DecrStatJob(job)
        sched.DecrStatProc(job)
    }
    return
}

func (sched *Sched) isDoJob(job Job) bool {
    now := time.Now()
    current := int64(now.Unix())
    ret := false
    for e := sched.jobQueue.Front(); e != nil; e = e.Next() {
        chk := e.Value.(Job)
        runAt := chk.RunAt
        if runAt < chk.SchedAt {
            runAt = chk.SchedAt
        }
        if chk.Timeout > 0 && runAt + chk.Timeout < current {
            newJob, _ := sched.store.Get(chk.Id)
            if newJob.Status == JOB_STATUS_PROC {
                sched.DecrStatProc(newJob)
                newJob.Status = JOB_STATUS_READY
                sched.store.Save(newJob)
                pq := sched.pq[newJob.Func]
                item := &Item{
                    value: newJob.Id,
                    priority: newJob.SchedAt,
                }
                heap.Push(pq, item)
            }
            sched.jobQueue.Remove(e)
            continue
        }
        if chk.Id == job.Id {
            old := e.Value.(Job)
            runAt := old.RunAt
            if runAt < old.SchedAt {
                runAt = old.SchedAt
            }
            if old.Timeout > 0 && runAt + old.Timeout < current {
                ret = false
            } else {
                ret = true
            }
        }
    }
    return ret
}

func (sched *Sched) SubmitJob(worker *Worker, job Job) {
    defer sched.JobLocker.Unlock()
    sched.JobLocker.Lock()
    if job.Name == "" {
        sched.store.Delete(job.Id)
        return
    }
    if sched.isDoJob(job) {
        return
    }
    if !worker.alive {
        return
    }
    if err := worker.HandleDo(job); err != nil {
        worker.alive = false
        go sched.DieWorker(worker)
        return
    }
    now := time.Now()
    current := int64(now.Unix())
    job.Status = JOB_STATUS_PROC
    job.RunAt = current
    sched.store.Save(job)
    sched.IncrStatProc(job)
    sched.jobQueue.PushBack(job)
    sched.removeGrabQueue(worker)
}

func (sched *Sched) handle() {
    var current time.Time
    var timestamp int64
    for {
        if sched.grabQueue.Len() == 0 {
            sched.timer.Reset(time.Minute)
            current =<-sched.timer.C
            continue
        }

        maybeItem := make(map[string]*Item)
        for Func, _ := range sched.Funcs {
            pq, ok := sched.pq[Func]
            if !ok || pq.Len() == 0 {
                continue
            }

            item := heap.Pop(pq).(*Item)

            maybeItem[Func] = item

        }

        if len(maybeItem) == 0 {
            sched.timer.Reset(time.Minute)
            current =<-sched.timer.C
        }

        var lessItem *Item
        var lessFunc string

        for Func, item := range maybeItem {
            if lessItem == nil {
                lessItem = item
                lessFunc = Func
                continue
            }
            if lessItem.priority > item.priority {
                lessItem = item
                lessFunc = Func
            }
        }

        for Func, item := range maybeItem {
            if Func == lessFunc {
                continue
            }
            pq := sched.pq[Func]
            heap.Push(pq, item)
        }

        schedJob, err := sched.store.Get(lessItem.value)

        if err != nil {
            continue
        }

        pq := sched.pq[schedJob.Func]
        timestamp = int64(time.Now().Unix())

        if schedJob.SchedAt > timestamp {
            sched.timer.Reset(time.Second * time.Duration(schedJob.SchedAt - timestamp))
            current =<-sched.timer.C
            timestamp = int64(current.Unix())
            if schedJob.SchedAt > timestamp {
                heap.Push(pq, lessItem)
                continue
            }
        }

        isSubmited := false
        for e := sched.grabQueue.Front(); e != nil; e = e.Next() {
            worker := e.Value.(*Worker)
            for _, Func := range worker.Funcs {
                if schedJob.Func == Func {
                    sched.SubmitJob(worker, schedJob)
                    isSubmited = true
                    break
                }
            }
            if isSubmited {
                break
            }
        }

        if !isSubmited {
            sched.DecrStatFunc(schedJob.Func)
        }
    }
}

func (sched *Sched) Fail(jobId int64) {
    defer sched.Notify()
    defer sched.JobLocker.Unlock()
    sched.JobLocker.Lock()
    removeListJob(sched.jobQueue, jobId)
    job, _ := sched.store.Get(jobId)
    sched.DecrStatProc(job)
    job.Status = JOB_STATUS_READY
    sched.store.Save(job)
    pq := sched.pq[job.Func]
    item := &Item{
        value: job.Id,
        priority: job.SchedAt,
    }
    heap.Push(pq, item)
    return
}

func (sched *Sched) IncrStatFunc(Func string) {
    stat, ok := sched.Funcs[Func]
    if !ok {
        stat = new(FuncStat)
        sched.Funcs[Func] = stat
    }
    stat.Worker.Incr()
}

func (sched *Sched) DecrStatFunc(Func string) {
    stat, ok := sched.Funcs[Func]
    if ok {
        stat.Worker.Decr()
    }
}

func (sched *Sched) IncrStatJob(job Job) {
    stat, ok := sched.Funcs[job.Func]
    if !ok {
        stat = new(FuncStat)
        sched.Funcs[job.Func] = stat
    }
    stat.Job.Incr()
}

func (sched *Sched) DecrStatJob(job Job) {
    stat, ok := sched.Funcs[job.Func]
    if ok {
        stat.Job.Decr()
    }
}

func (sched *Sched) IncrStatProc(job Job) {
    stat, ok := sched.Funcs[job.Func]
    if !ok {
        stat = new(FuncStat)
        sched.Funcs[job.Func] = stat
    }
    if job.Status == JOB_STATUS_PROC {
        stat.Processing.Incr()
    }
}

func (sched *Sched) DecrStatProc(job Job) {
    stat, ok := sched.Funcs[job.Func]
    if ok && job.Status == JOB_STATUS_PROC {
        stat.Processing.Decr()
    }
}

func (sched *Sched) SchedLater(jobId int64, delay int64) {
    defer sched.Notify()
    defer sched.JobLocker.Unlock()
    sched.JobLocker.Lock()
    removeListJob(sched.jobQueue, jobId)
    job, _ := sched.store.Get(jobId)
    sched.DecrStatProc(job)
    job.Status = JOB_STATUS_READY
    var now = time.Now()
    job.SchedAt = int64(now.Unix()) + delay
    sched.store.Save(job)
    pq := sched.pq[job.Func]
    item := &Item{
        value: job.Id,
        priority: job.SchedAt,
    }
    heap.Push(pq, item)
    return
}

func (sched *Sched) removeGrabQueue(worker *Worker) {
    for e := sched.grabQueue.Front(); e != nil; e = e.Next() {
        if e.Value.(*Worker) == worker {
            sched.grabQueue.Remove(e)
        }
    }
}

func (sched *Sched) checkJobQueue() {
    updateQueue := make([]Job, 0)
    removeQueue := make([]Job, 0)
    var now = time.Now()
    current := int64(now.Unix())

    iter := sched.store.NewIterator(nil, nil)
    for {
        if !iter.Next() {
            break
        }
        job := iter.Value()
        if job.Name == "" {
            removeQueue = append(removeQueue, job)
            continue
        }
        sched.IncrStatJob(job)
        if job.Status != JOB_STATUS_PROC {
            pq, ok := sched.pq[job.Func]
            if !ok {
                pq1 := make(PriorityQueue, 0)
                pq = &pq1
                sched.pq[job.Func] = pq
                heap.Init(pq)
            }
            item := &Item{
                value: job.Id,
                priority: job.SchedAt,
            }
            heap.Push(pq, item)
            continue
        }
        runAt := job.RunAt
        if runAt < job.SchedAt {
            runAt = job.SchedAt
        }
        if runAt + job.Timeout < current {
            updateQueue = append(updateQueue, job)
        } else {
            sched.jobQueue.PushBack(job)
            sched.IncrStatProc(job)
        }
    }

    iter.Close()

    for _, job := range updateQueue {
        job.Status = JOB_STATUS_READY
        sched.store.Save(job)
    }

    for _, job := range removeQueue {
        sched.store.Delete(job.Id)
    }
}

func (sched *Sched) Close() {
}
<|endoftext|>


<commit_before>/*
Copyright 2016 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 kuberuntime

import (
	"fmt"

	"k8s.io/kubernetes/pkg/api/v1"
	runtimeapi "k8s.io/kubernetes/pkg/kubelet/api/v1alpha1/runtime"
	"k8s.io/kubernetes/pkg/securitycontext"
)

// determineEffectiveSecurityContext gets container's security context from v1.Pod and v1.Container.
func (m *kubeGenericRuntimeManager) determineEffectiveSecurityContext(pod *v1.Pod, container *v1.Container, uid *int64, username string) *runtimeapi.LinuxContainerSecurityContext {
	effectiveSc := securitycontext.DetermineEffectiveSecurityContext(pod, container)
	synthesized := convertToRuntimeSecurityContext(effectiveSc)
	if synthesized == nil {
		synthesized = &runtimeapi.LinuxContainerSecurityContext{}
	}

	// set RunAsUser.
	if synthesized.RunAsUser == nil {
		if uid != nil {
			synthesized.RunAsUser = &runtimeapi.Int64Value{Value: *uid}
		}
		synthesized.RunAsUsername = username
	}

	// set namespace options and supplemental groups.
	podSc := pod.Spec.SecurityContext
	if podSc == nil {
		return synthesized
	}
	synthesized.NamespaceOptions = &runtimeapi.NamespaceOption{
		HostNetwork: pod.Spec.HostNetwork,
		HostIpc:     pod.Spec.HostIPC,
		HostPid:     pod.Spec.HostPID,
	}
	if podSc.FSGroup != nil {
		synthesized.SupplementalGroups = append(synthesized.SupplementalGroups, *podSc.FSGroup)
	}
	if groups := m.runtimeHelper.GetExtraSupplementalGroupsForPod(pod); len(groups) > 0 {
		synthesized.SupplementalGroups = append(synthesized.SupplementalGroups, groups...)
	}
	if podSc.SupplementalGroups != nil {
		synthesized.SupplementalGroups = append(synthesized.SupplementalGroups, podSc.SupplementalGroups...)
	}

	return synthesized
}

// verifyRunAsNonRoot verifies RunAsNonRoot.
func verifyRunAsNonRoot(pod *v1.Pod, container *v1.Container, uid int64) error {
	effectiveSc := securitycontext.DetermineEffectiveSecurityContext(pod, container)
	if effectiveSc == nil || effectiveSc.RunAsNonRoot == nil {
		return nil
	}

	if effectiveSc.RunAsUser != nil {
		if *effectiveSc.RunAsUser == 0 {
			return fmt.Errorf("container's runAsUser breaks non-root policy")
		}
		return nil
	}

	if uid == 0 {
		return fmt.Errorf("container has runAsNonRoot and image will run as root")
	}

	return nil
}

// convertToRuntimeSecurityContext converts v1.SecurityContext to runtimeapi.SecurityContext.
func convertToRuntimeSecurityContext(securityContext *v1.SecurityContext) *runtimeapi.LinuxContainerSecurityContext {
	if securityContext == nil {
		return nil
	}

	sc := &runtimeapi.LinuxContainerSecurityContext{
		Capabilities:   convertToRuntimeCapabilities(securityContext.Capabilities),
		SelinuxOptions: convertToRuntimeSELinuxOption(securityContext.SELinuxOptions),
	}
	if securityContext.RunAsUser != nil {
		sc.RunAsUser = &runtimeapi.Int64Value{Value: *securityContext.RunAsUser}
	}
	if securityContext.Privileged != nil {
		sc.Privileged = *securityContext.Privileged
	}
	if securityContext.ReadOnlyRootFilesystem != nil {
		sc.ReadonlyRootfs = *securityContext.ReadOnlyRootFilesystem
	}

	return sc
}

// convertToRuntimeSELinuxOption converts v1.SELinuxOptions to runtimeapi.SELinuxOption.
func convertToRuntimeSELinuxOption(opts *v1.SELinuxOptions) *runtimeapi.SELinuxOption {
	if opts == nil {
		return nil
	}

	return &runtimeapi.SELinuxOption{
		User:  opts.User,
		Role:  opts.Role,
		Type:  opts.Type,
		Level: opts.Level,
	}
}

// convertToRuntimeCapabilities converts v1.Capabilities to runtimeapi.Capability.
func convertToRuntimeCapabilities(opts *v1.Capabilities) *runtimeapi.Capability {
	if opts == nil {
		return nil
	}

	capabilities := &runtimeapi.Capability{
		AddCapabilities:  make([]string, len(opts.Add)),
		DropCapabilities: make([]string, len(opts.Drop)),
	}
	for index, value := range opts.Add {
		capabilities.AddCapabilities[index] = string(value)
	}
	for index, value := range opts.Drop {
		capabilities.DropCapabilities[index] = string(value)
	}

	return capabilities
}
<commit_msg>kuberuntime: set namespsace options regardless of security context<commit_after>/*
Copyright 2016 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 kuberuntime

import (
	"fmt"

	"k8s.io/kubernetes/pkg/api/v1"
	runtimeapi "k8s.io/kubernetes/pkg/kubelet/api/v1alpha1/runtime"
	"k8s.io/kubernetes/pkg/securitycontext"
)

// determineEffectiveSecurityContext gets container's security context from v1.Pod and v1.Container.
func (m *kubeGenericRuntimeManager) determineEffectiveSecurityContext(pod *v1.Pod, container *v1.Container, uid *int64, username string) *runtimeapi.LinuxContainerSecurityContext {
	effectiveSc := securitycontext.DetermineEffectiveSecurityContext(pod, container)
	synthesized := convertToRuntimeSecurityContext(effectiveSc)
	if synthesized == nil {
		synthesized = &runtimeapi.LinuxContainerSecurityContext{}
	}

	// set RunAsUser.
	if synthesized.RunAsUser == nil {
		if uid != nil {
			synthesized.RunAsUser = &runtimeapi.Int64Value{Value: *uid}
		}
		synthesized.RunAsUsername = username
	}

	// set namespace options and supplemental groups.
	synthesized.NamespaceOptions = &runtimeapi.NamespaceOption{
		HostNetwork: pod.Spec.HostNetwork,
		HostIpc:     pod.Spec.HostIPC,
		HostPid:     pod.Spec.HostPID,
	}
	podSc := pod.Spec.SecurityContext
	if podSc != nil {
		if podSc.FSGroup != nil {
			synthesized.SupplementalGroups = append(synthesized.SupplementalGroups, *podSc.FSGroup)
		}

		if podSc.SupplementalGroups != nil {
			synthesized.SupplementalGroups = append(synthesized.SupplementalGroups, podSc.SupplementalGroups...)
		}
	}
	if groups := m.runtimeHelper.GetExtraSupplementalGroupsForPod(pod); len(groups) > 0 {
		synthesized.SupplementalGroups = append(synthesized.SupplementalGroups, groups...)
	}

	return synthesized
}

// verifyRunAsNonRoot verifies RunAsNonRoot.
func verifyRunAsNonRoot(pod *v1.Pod, container *v1.Container, uid int64) error {
	effectiveSc := securitycontext.DetermineEffectiveSecurityContext(pod, container)
	if effectiveSc == nil || effectiveSc.RunAsNonRoot == nil {
		return nil
	}

	if effectiveSc.RunAsUser != nil {
		if *effectiveSc.RunAsUser == 0 {
			return fmt.Errorf("container's runAsUser breaks non-root policy")
		}
		return nil
	}

	if uid == 0 {
		return fmt.Errorf("container has runAsNonRoot and image will run as root")
	}

	return nil
}

// convertToRuntimeSecurityContext converts v1.SecurityContext to runtimeapi.SecurityContext.
func convertToRuntimeSecurityContext(securityContext *v1.SecurityContext) *runtimeapi.LinuxContainerSecurityContext {
	if securityContext == nil {
		return nil
	}

	sc := &runtimeapi.LinuxContainerSecurityContext{
		Capabilities:   convertToRuntimeCapabilities(securityContext.Capabilities),
		SelinuxOptions: convertToRuntimeSELinuxOption(securityContext.SELinuxOptions),
	}
	if securityContext.RunAsUser != nil {
		sc.RunAsUser = &runtimeapi.Int64Value{Value: *securityContext.RunAsUser}
	}
	if securityContext.Privileged != nil {
		sc.Privileged = *securityContext.Privileged
	}
	if securityContext.ReadOnlyRootFilesystem != nil {
		sc.ReadonlyRootfs = *securityContext.ReadOnlyRootFilesystem
	}

	return sc
}

// convertToRuntimeSELinuxOption converts v1.SELinuxOptions to runtimeapi.SELinuxOption.
func convertToRuntimeSELinuxOption(opts *v1.SELinuxOptions) *runtimeapi.SELinuxOption {
	if opts == nil {
		return nil
	}

	return &runtimeapi.SELinuxOption{
		User:  opts.User,
		Role:  opts.Role,
		Type:  opts.Type,
		Level: opts.Level,
	}
}

// convertToRuntimeCapabilities converts v1.Capabilities to runtimeapi.Capability.
func convertToRuntimeCapabilities(opts *v1.Capabilities) *runtimeapi.Capability {
	if opts == nil {
		return nil
	}

	capabilities := &runtimeapi.Capability{
		AddCapabilities:  make([]string, len(opts.Add)),
		DropCapabilities: make([]string, len(opts.Drop)),
	}
	for index, value := range opts.Add {
		capabilities.AddCapabilities[index] = string(value)
	}
	for index, value := range opts.Drop {
		capabilities.DropCapabilities[index] = string(value)
	}

	return capabilities
}
<|endoftext|>


<commit_before>/*
Copyright 2018 The Rook Authors. All rights reserved.

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

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

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

// Package objectuser to manage a rook object store user.
package objectuser

import (
	"fmt"
	"reflect"

	"github.com/coreos/pkg/capnslog"
	opkit "github.com/rook/operator-kit"
	cephv1 "github.com/rook/rook/pkg/apis/ceph.rook.io/v1"
	"github.com/rook/rook/pkg/clusterd"
	cephconfig "github.com/rook/rook/pkg/daemon/ceph/config"
	"github.com/rook/rook/pkg/operator/ceph/object"
	"github.com/rook/rook/pkg/operator/k8sutil"
	v1 "k8s.io/api/core/v1"
	apiextensionsv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/client-go/tools/cache"
)

const (
	appName = object.AppName
)

var logger = capnslog.NewPackageLogger("github.com/rook/rook", "op-object")

// ObjectStoreUserResource represents the object store user custom resource
var ObjectStoreUserResource = opkit.CustomResource{
	Name:    "cephobjectstoreuser",
	Plural:  "cephobjectstoreusers",
	Group:   cephv1.CustomResourceGroup,
	Version: cephv1.Version,
	Scope:   apiextensionsv1beta1.NamespaceScoped,
	Kind:    reflect.TypeOf(cephv1.CephObjectStoreUser{}).Name(),
}

// ObjectStoreUserController represents a controller object for object store user custom resources
type ObjectStoreUserController struct {
	context     *clusterd.Context
	ownerRef    metav1.OwnerReference
	clusterSpec *cephv1.ClusterSpec
	namespace   string
}

// NewObjectStoreUserController create controller for watching object store user custom resources created
func NewObjectStoreUserController(context *clusterd.Context, clusterSpec *cephv1.ClusterSpec, namespace string, ownerRef metav1.OwnerReference) *ObjectStoreUserController {
	return &ObjectStoreUserController{
		context:     context,
		ownerRef:    ownerRef,
		clusterSpec: clusterSpec,
		namespace:   namespace,
	}
}

// StartWatch watches for instances of ObjectStoreUser custom resources and acts on them
func (c *ObjectStoreUserController) StartWatch(stopCh chan struct{}) error {

	resourceHandlerFuncs := cache.ResourceEventHandlerFuncs{
		AddFunc:    c.onAdd,
		UpdateFunc: c.onUpdate,
		DeleteFunc: c.onDelete,
	}

	logger.Infof("start watching object store user resources in namespace %s", c.namespace)
	watcher := opkit.NewWatcher(ObjectStoreUserResource, c.namespace, resourceHandlerFuncs, c.context.RookClientset.CephV1().RESTClient())
	go watcher.Watch(&cephv1.CephObjectStoreUser{}, stopCh)

	return nil
}

func (c *ObjectStoreUserController) onAdd(obj interface{}) {
	user, err := getObjectStoreUserObject(obj)
	if err != nil {
		logger.Errorf("failed to get objectstoreuser object: %+v", err)
		return
	}

	if err = c.createUser(c.context, user); err != nil {
		logger.Errorf("failed to create object store user %s. %+v", user.Name, err)
	}
}

func (c *ObjectStoreUserController) onUpdate(oldObj, newObj interface{}) {
	// TODO: Add update code here after features are added which require updates.
}

func (c *ObjectStoreUserController) onDelete(obj interface{}) {
	user, err := getObjectStoreUserObject(obj)
	if err != nil {
		logger.Errorf("failed to get objectstoreuser object: %+v", err)
		return
	}

	if err = deleteUser(c.context, user); err != nil {
		logger.Errorf("failed to delete object store user %s. %+v", user.Name, err)
	}
}

func (c *ObjectStoreUserController) ParentClusterChanged(cluster cephv1.ClusterSpec, clusterInfo *cephconfig.ClusterInfo) {
	logger.Debugf("No need to update object store users after the parent cluster changed")
}

func (c *ObjectStoreUserController) storeUserOwners(store *cephv1.CephObjectStoreUser) []metav1.OwnerReference {
	// Only set the cluster crd as the owner of the object store user resources.
	// If the object store user crd is deleted, the operator will explicitly remove the object store user resources.
	// If the object store user crd still exists when the cluster crd is deleted, this will make sure the object store user
	// resources are cleaned up.
	return []metav1.OwnerReference{c.ownerRef}
}

func getObjectStoreUserObject(obj interface{}) (objectstoreuser *cephv1.CephObjectStoreUser, err error) {
	var ok bool
	objectstoreuser, ok = obj.(*cephv1.CephObjectStoreUser)
	if ok {
		// the objectstoreuser object is of the latest type, simply return it
		return objectstoreuser.DeepCopy(), nil
	}
	return nil, fmt.Errorf("not a known objectstoreuser object: %+v", obj)
}

// Create the user
func (c *ObjectStoreUserController) createUser(context *clusterd.Context, u *cephv1.CephObjectStoreUser) error {
	// validate the user settings
	if err := ValidateUser(context, u); err != nil {
		return fmt.Errorf("invalid user %s arguments. %+v", u.Name, err)
	}
	// Set DisplayName to match Name if DisplayName is not set
	displayName := u.Spec.DisplayName
	if len(displayName) == 0 {
		displayName = u.Name
	}

	// create the user
	logger.Infof("creating user %s in namespace %s", u.Name, u.Namespace)
	userConfig := object.ObjectUser{
		UserID:      u.Name,
		DisplayName: &displayName,
	}
	objContext := object.NewContext(context, u.Spec.Store, u.Namespace)

	user, rgwerr, err := object.CreateUser(objContext, userConfig)
	if err != nil {
		return fmt.Errorf("failed to create user %s. RadosGW returned error %d: %+v", u.Name, rgwerr, err)
	}

	// Store the keys in a secret
	secrets := map[string]string{
		"AccessKey": *user.AccessKey,
		"SecretKey": *user.SecretKey,
	}
	secret := &v1.Secret{
		ObjectMeta: metav1.ObjectMeta{
			Name:      fmt.Sprintf("rook-ceph-object-user-%s-%s", u.Spec.Store, u.Name),
			Namespace: u.Namespace,
			Labels: map[string]string{
				"app":               appName,
				"user":              u.Name,
				"rook_cluster":      u.Namespace,
				"rook_object_store": u.Spec.Store,
			},
		},
		StringData: secrets,
		Type:       k8sutil.RookType,
	}
	k8sutil.SetOwnerRef(&secret.ObjectMeta, &c.ownerRef)

	_, err = context.Clientset.CoreV1().Secrets(u.Namespace).Create(secret)
	if err != nil {
		return fmt.Errorf("failed to save user %s secret. %+v", u.Name, err)
	}
	logger.Infof("created user %s", u.Name)
	return nil
}

// Delete the user
func deleteUser(context *clusterd.Context, u *cephv1.CephObjectStoreUser) error {
	objContext := object.NewContext(context, u.Spec.Store, u.Namespace)
	_, rgwerr, err := object.DeleteUser(objContext, u.Name)
	if err != nil {
		if rgwerr == 3 {
			logger.Infof("user %s does not exist in store %s", u.Name, u.Spec.Store)
		} else {
			return fmt.Errorf("failed to delete user '%s': %+v", u.Name, err)
		}
	}

	err = context.Clientset.CoreV1().Secrets(u.Namespace).Delete(fmt.Sprintf("rook-ceph-object-user-%s-%s", u.Spec.Store, u.Name), &metav1.DeleteOptions{})
	if err != nil {
		logger.Warningf("failed to delete user %s secret. %+v", fmt.Sprintf("rook-ceph-object-user-%s-%s", u.Spec.Store, u.Name), err)
	}

	logger.Infof("user %s deleted successfully", u.Name)
	return nil
}

// ValidateUser validates the user arguments
func ValidateUser(context *clusterd.Context, u *cephv1.CephObjectStoreUser) error {
	if u.Name == "" {
		return fmt.Errorf("missing name")
	}
	if u.Namespace == "" {
		return fmt.Errorf("missing namespace")
	}
	if u.Spec.Store == "" {
		return fmt.Errorf("missing store")
	}
	return nil
}
<commit_msg>adds wait.Poll to create ObjectUser<commit_after>/*
Copyright 2018 The Rook Authors. All rights reserved.

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

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

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

// Package objectuser to manage a rook object store user.
package objectuser

import (
	"fmt"
	"reflect"
	"time"

	"k8s.io/apimachinery/pkg/api/errors"
	"k8s.io/apimachinery/pkg/util/wait"

	"github.com/coreos/pkg/capnslog"
	opkit "github.com/rook/operator-kit"
	cephv1 "github.com/rook/rook/pkg/apis/ceph.rook.io/v1"
	"github.com/rook/rook/pkg/clusterd"
	cephconfig "github.com/rook/rook/pkg/daemon/ceph/config"
	"github.com/rook/rook/pkg/operator/ceph/object"
	"github.com/rook/rook/pkg/operator/k8sutil"
	v1 "k8s.io/api/core/v1"
	apiextensionsv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/client-go/tools/cache"
)

const (
	appName = object.AppName
)

var logger = capnslog.NewPackageLogger("github.com/rook/rook", "op-object")

// ObjectStoreUserResource represents the object store user custom resource
var ObjectStoreUserResource = opkit.CustomResource{
	Name:    "cephobjectstoreuser",
	Plural:  "cephobjectstoreusers",
	Group:   cephv1.CustomResourceGroup,
	Version: cephv1.Version,
	Scope:   apiextensionsv1beta1.NamespaceScoped,
	Kind:    reflect.TypeOf(cephv1.CephObjectStoreUser{}).Name(),
}

// ObjectStoreUserController represents a controller object for object store user custom resources
type ObjectStoreUserController struct {
	context     *clusterd.Context
	ownerRef    metav1.OwnerReference
	clusterSpec *cephv1.ClusterSpec
	namespace   string
}

// NewObjectStoreUserController create controller for watching object store user custom resources created
func NewObjectStoreUserController(context *clusterd.Context, clusterSpec *cephv1.ClusterSpec, namespace string, ownerRef metav1.OwnerReference) *ObjectStoreUserController {
	return &ObjectStoreUserController{
		context:     context,
		ownerRef:    ownerRef,
		clusterSpec: clusterSpec,
		namespace:   namespace,
	}
}

// StartWatch watches for instances of ObjectStoreUser custom resources and acts on them
func (c *ObjectStoreUserController) StartWatch(stopCh chan struct{}) error {

	resourceHandlerFuncs := cache.ResourceEventHandlerFuncs{
		AddFunc:    c.onAdd,
		UpdateFunc: c.onUpdate,
		DeleteFunc: c.onDelete,
	}

	logger.Infof("start watching object store user resources in namespace %s", c.namespace)
	watcher := opkit.NewWatcher(ObjectStoreUserResource, c.namespace, resourceHandlerFuncs, c.context.RookClientset.CephV1().RESTClient())
	go watcher.Watch(&cephv1.CephObjectStoreUser{}, stopCh)

	return nil
}

func (c *ObjectStoreUserController) onAdd(obj interface{}) {
	user, err := getObjectStoreUserObject(obj)
	if err != nil {
		logger.Errorf("failed to get objectstoreuser object: %+v", err)
		return
	}

	if err = c.createUser(c.context, user); err != nil {
		logger.Errorf("failed to create object store user %s. %+v", user.Name, err)
	}
}

func (c *ObjectStoreUserController) onUpdate(oldObj, newObj interface{}) {
	// TODO: Add update code here after features are added which require updates.
}

func (c *ObjectStoreUserController) onDelete(obj interface{}) {
	user, err := getObjectStoreUserObject(obj)
	if err != nil {
		logger.Errorf("failed to get objectstoreuser object: %+v", err)
		return
	}

	if err = deleteUser(c.context, user); err != nil {
		logger.Errorf("failed to delete object store user %s. %+v", user.Name, err)
	}
}

func (c *ObjectStoreUserController) ParentClusterChanged(cluster cephv1.ClusterSpec, clusterInfo *cephconfig.ClusterInfo) {
	logger.Debugf("No need to update object store users after the parent cluster changed")
}

func (c *ObjectStoreUserController) storeUserOwners(store *cephv1.CephObjectStoreUser) []metav1.OwnerReference {
	// Only set the cluster crd as the owner of the object store user resources.
	// If the object store user crd is deleted, the operator will explicitly remove the object store user resources.
	// If the object store user crd still exists when the cluster crd is deleted, this will make sure the object store user
	// resources are cleaned up.
	return []metav1.OwnerReference{c.ownerRef}
}

func getObjectStoreUserObject(obj interface{}) (objectstoreuser *cephv1.CephObjectStoreUser, err error) {
	var ok bool
	objectstoreuser, ok = obj.(*cephv1.CephObjectStoreUser)
	if ok {
		// the objectstoreuser object is of the latest type, simply return it
		return objectstoreuser.DeepCopy(), nil
	}
	return nil, fmt.Errorf("not a known objectstoreuser object: %+v", obj)
}

// Create the user
func (c *ObjectStoreUserController) createUser(context *clusterd.Context, u *cephv1.CephObjectStoreUser) error {
	// validate the user settings
	if err := ValidateUser(context, u); err != nil {
		return fmt.Errorf("invalid user %s arguments. %+v", u.Name, err)
	}
	// Set DisplayName to match Name if DisplayName is not set
	displayName := u.Spec.DisplayName
	if len(displayName) == 0 {
		displayName = u.Name
	}

	// create the user
	logger.Infof("creating user %s in namespace %s", u.Name, u.Namespace)
	userConfig := object.ObjectUser{
		UserID:      u.Name,
		DisplayName: &displayName,
	}
	objContext := object.NewContext(context, u.Spec.Store, u.Namespace)

	err := wait.Poll(time.Second*15, time.Minute*5, func() (ok bool, err error) {
		// check if CephObjectStore CR is created
		logger.Infof("waiting for CephObjectStore %s to be created", u.Spec.Store)
		_, err = context.RookClientset.CephV1().CephObjectStores(u.Namespace).Get(u.Spec.Store, metav1.GetOptions{})
		// wait only if objectStore is not found. return on any other error
		if err != nil {
			if errors.IsNotFound(err) {
				return false, nil
			}
			logger.Errorf("CephObjectStore %s could not be found. %+v", u.Spec.Store, err)
			return true, err
		}
		// check if ObjectStore is initialized
		// rook does this by starting the RGW pod(s)
		selector := fmt.Sprintf("%s=%s,%s=%s",
			"rgw", u.Spec.Store,
			k8sutil.AppAttr, appName,
		)
		logger.Infof("waiting for CephObjectStore %s to be initialized", u.Spec.Store)
		pods, err := context.Clientset.CoreV1().Pods(u.Namespace).List(metav1.ListOptions{LabelSelector: selector, FieldSelector: "status.phase=Running"})
		if err != nil {
			if errors.IsNotFound(err) {
				return false, nil
			}
			logger.Errorf("CephObjectStore %s may not be initialized. %+v", u.Spec.Store, err)
			return true, err
		}
		// check if atleast one pod is running
		if pods != nil {
			logger.Infof("CephObjectStore %s has been created successfully", u.Spec.Store)
			return true, nil
		}
		return false, nil
	})
	if err != nil {
		logger.Errorf("timed out while waiting for objectstore %s to be ready. %+v", u.Spec.Store, err)
	}

	user, rgwerr, err := object.CreateUser(objContext, userConfig)
	if err != nil {
		return fmt.Errorf("failed to create user %s. RadosGW returned error %d: %+v", u.Name, rgwerr, err)
	}

	// Store the keys in a secret
	secrets := map[string]string{
		"AccessKey": *user.AccessKey,
		"SecretKey": *user.SecretKey,
	}
	secret := &v1.Secret{
		ObjectMeta: metav1.ObjectMeta{
			Name:      fmt.Sprintf("rook-ceph-object-user-%s-%s", u.Spec.Store, u.Name),
			Namespace: u.Namespace,
			Labels: map[string]string{
				"app":               appName,
				"user":              u.Name,
				"rook_cluster":      u.Namespace,
				"rook_object_store": u.Spec.Store,
			},
		},
		StringData: secrets,
		Type:       k8sutil.RookType,
	}
	k8sutil.SetOwnerRef(&secret.ObjectMeta, &c.ownerRef)

	_, err = context.Clientset.CoreV1().Secrets(u.Namespace).Create(secret)
	if err != nil {
		return fmt.Errorf("failed to save user %s secret. %+v", u.Name, err)
	}
	logger.Infof("created user %s", u.Name)
	return nil
}

// Delete the user
func deleteUser(context *clusterd.Context, u *cephv1.CephObjectStoreUser) error {
	objContext := object.NewContext(context, u.Spec.Store, u.Namespace)
	_, rgwerr, err := object.DeleteUser(objContext, u.Name)
	if err != nil {
		if rgwerr == 3 {
			logger.Infof("user %s does not exist in store %s", u.Name, u.Spec.Store)
		} else {
			return fmt.Errorf("failed to delete user '%s': %+v", u.Name, err)
		}
	}

	err = context.Clientset.CoreV1().Secrets(u.Namespace).Delete(fmt.Sprintf("rook-ceph-object-user-%s-%s", u.Spec.Store, u.Name), &metav1.DeleteOptions{})
	if err != nil {
		logger.Warningf("failed to delete user %s secret. %+v", fmt.Sprintf("rook-ceph-object-user-%s-%s", u.Spec.Store, u.Name), err)
	}

	logger.Infof("user %s deleted successfully", u.Name)
	return nil
}

// ValidateUser validates the user arguments
func ValidateUser(context *clusterd.Context, u *cephv1.CephObjectStoreUser) error {
	if u.Name == "" {
		return fmt.Errorf("missing name")
	}
	if u.Namespace == "" {
		return fmt.Errorf("missing namespace")
	}
	if u.Spec.Store == "" {
		return fmt.Errorf("missing store")
	}
	return nil
}
<|endoftext|>