From 6e7516cd8e43ad13a87f246cc5f11a3a1c8c3a92 Mon Sep 17 00:00:00 2001 From: shay-berman Date: Wed, 28 Mar 2018 17:27:07 +0300 Subject: [PATCH 01/40] Fix/Flex mount idempotent improvements (#177) * place holders comments for potential idempotent fixes - unmount and mount flow * Idempotent : if vol not exit fail + start add unit testing * Idempotent Mount func : fix NewControllerWithClient, refactor doMount to small functions and add unit test for them(phase1) * mount idempotent : fix mounter.Mount unit test and get fakes from ubiquity in glide * mount idempotent : full coverage of unit testing for controller.Mount() + fix bug - Fix bug - return error when slink removal failed - Convert os ops in Mount() to use the standard exec.os to allow mocking * mount idempotent: controller.Mount fix issues with PV dir removal and slink aspects + 100% UT coverage * In addition - for provisioner side of thing - just add logging for create and delete volume --- cmd/flex/main/cli.go | 2 +- controller/controller.go | 238 ++++++++++++++------ controller/controller_test.go | 402 +++++++++++++++++++++++++++++++++- controller/errors.go | 72 ++++++ glide.yaml | 2 + volume/provision.go | 8 + 6 files changed, 650 insertions(+), 74 deletions(-) create mode 100644 controller/errors.go diff --git a/cmd/flex/main/cli.go b/cmd/flex/main/cli.go index 70cecb3aa..ddfc43c4c 100644 --- a/cmd/flex/main/cli.go +++ b/cmd/flex/main/cli.go @@ -394,7 +394,7 @@ func (m *MountCommand) Execute(args []string) error { mountRequest := k8sresources.FlexVolumeMountRequest{ MountPath: targetMountDir, - MountDevice: volumeName, + MountDevice: volumeName, // The PV name Opts: mountOpts, Version: version, } diff --git a/controller/controller.go b/controller/controller.go index 67316f621..db664c965 100644 --- a/controller/controller.go +++ b/controller/controller.go @@ -20,13 +20,10 @@ import ( "fmt" "log" "os" - "os/exec" "path" "strings" "github.com/IBM/ubiquity/utils/logs" - - "bytes" k8sresources "github.com/IBM/ubiquity-k8s/resources" "github.com/IBM/ubiquity/remote" "github.com/IBM/ubiquity/resources" @@ -37,6 +34,9 @@ import ( "time" ) +const FlexSuccessStr = "Success" +const FlexFailureStr = "Failure" + //Controller this is a structure that controls volume management type Controller struct { Client resources.StorageClient @@ -46,6 +46,7 @@ type Controller struct { config resources.UbiquityPluginConfig mounterPerBackend map[string]resources.Mounter unmountFlock lockfile.Lockfile + mounterFactory mounter.MounterFactory } //NewController allows to instantiate a controller @@ -66,18 +67,30 @@ func NewController(logger *log.Logger, config resources.UbiquityPluginConfig) (* exec: utils.NewExecutor(), config: config, mounterPerBackend: make(map[string]resources.Mounter), - unmountFlock: unmountFlock}, nil + unmountFlock: unmountFlock, + mounterFactory: mounter.NewMounterFactory(), + }, nil } + + //NewControllerWithClient is made for unit testing purposes where we can pass a fake client -func NewControllerWithClient(logger *log.Logger, client resources.StorageClient, exec utils.Executor) *Controller { +func NewControllerWithClient(logger *log.Logger, config resources.UbiquityPluginConfig, client resources.StorageClient, exec utils.Executor, mFactory mounter.MounterFactory) *Controller { unmountFlock, err := lockfile.New(filepath.Join(os.TempDir(), "ubiquity.unmount.lock")) if err != nil { panic(err) } - utils.NewExecutor() - return &Controller{logger: logs.GetLogger(), legacyLogger: logger, Client: client, exec: exec, unmountFlock: unmountFlock} + return &Controller{ + logger: logs.GetLogger(), + legacyLogger: logger, + Client: client, + exec: exec, + config: config, + mounterPerBackend: make(map[string]resources.Mounter), + unmountFlock: unmountFlock, + mounterFactory: mFactory, + } } @@ -261,6 +274,7 @@ func (c *Controller) Mount(mountRequest k8sresources.FlexVolumeMountRequest) k8s var response k8sresources.FlexVolumeResponse c.logger.Debug("", logs.Args{{"request", mountRequest}}) + // TODO check if volume exist first and what its backend type mountedPath, err := c.doMount(mountRequest) if err != nil { response = k8sresources.FlexVolumeResponse{ @@ -308,6 +322,8 @@ func (c *Controller) Unmount(unmountRequest k8sresources.FlexVolumeUnmountReques // Validate that the mountpoint is a symlink as ubiquity expect it to be realMountPoint, err := c.exec.EvalSymlinks(unmountRequest.MountPath) + // TODO idempotent, don't use EvalSymlinks to identify the backend, instead check the volume backend. In addition when we check the eval of the slink, if its not exist we should jump to detach (if its not slink then we should fail) + if err != nil { msg := fmt.Sprintf("Cannot execute umount because the mountPath [%s] is not a symlink as expected. Error: %#v", unmountRequest.MountPath, err) c.logger.Error(msg) @@ -367,48 +383,81 @@ func (c *Controller) doLegacyDetach(unmountRequest k8sresources.FlexVolumeUnmoun func (c *Controller) getMounterForBackend(backend string) (resources.Mounter, error) { defer c.logger.Trace(logs.DEBUG)() + var err error mounterInst, ok := c.mounterPerBackend[backend] if ok { + // mounter already exist in the controller backend list return mounterInst, nil - } else if backend == resources.SpectrumScale { - c.mounterPerBackend[backend] = mounter.NewSpectrumScaleMounter(c.legacyLogger) - } else if backend == resources.SoftlayerNFS || backend == resources.SpectrumScaleNFS { - c.mounterPerBackend[backend] = mounter.NewNfsMounter(c.legacyLogger) - } else if backend == resources.SCBE { - c.mounterPerBackend[backend] = mounter.NewScbeMounter(c.config.ScbeRemoteConfig) } else { - err := fmt.Errorf("Mounter not found for backend: %s", backend) - return nil, c.logger.ErrorRet(err, "failed") + // mounter not exist in the controller backend list, so get it now + c.mounterPerBackend[backend], err = c.mounterFactory.GetMounterPerBackend(backend, c.legacyLogger, c.config) + if err != nil { + return nil, err + } } return c.mounterPerBackend[backend], nil } -func (c *Controller) doMount(mountRequest k8sresources.FlexVolumeMountRequest) (string, error) { + +func (c *Controller) prepareUbiquityMountRequest(mountRequest k8sresources.FlexVolumeMountRequest) (resources.MountRequest, error) { + /* + Prepare the mounter.Mount request + */ defer c.logger.Trace(logs.DEBUG)() - name := mountRequest.MountDevice - getVolumeConfigRequest := resources.GetVolumeConfigRequest{Name: name} + // Prepare request for mounter - step1 get volume's config from ubiquity + getVolumeConfigRequest := resources.GetVolumeConfigRequest{Name: mountRequest.MountDevice} volumeConfig, err := c.Client.GetVolumeConfig(getVolumeConfigRequest) if err != nil { - return "", c.logger.ErrorRet(err, "Client.GetVolumeConfig failed") + return resources.MountRequest{}, c.logger.ErrorRet(err, "Client.GetVolumeConfig failed") + } + + // Prepare request for mounter - step2 generate the designated mountpoint for this volume. + // TODO should be agnostic to the backend, currently its scbe oriented. + wwn, ok := mountRequest.Opts["Wwn"] + if !ok { + err = fmt.Errorf(MissingWwnMountRequestErrorStr) + return resources.MountRequest{}, c.logger.ErrorRet(err, "failed") } + volumeMountpoint := fmt.Sprintf(resources.PathToMountUbiquityBlockDevices, wwn) + ubMountRequest := resources.MountRequest{Mountpoint: volumeMountpoint, VolumeConfig: volumeConfig} + return ubMountRequest, nil +} + +func (c *Controller) getMounterByPV(pvname string) (resources.Mounter, error) { + defer c.logger.Trace(logs.DEBUG)() - getVolumeRequest := resources.GetVolumeRequest{Name: name} + getVolumeRequest := resources.GetVolumeRequest{Name: pvname} volume, err := c.Client.GetVolume(getVolumeRequest) + if err != nil { + return nil, c.logger.ErrorRet(err, "GetVolume failed") + } mounter, err := c.getMounterForBackend(volume.Backend) if err != nil { - err = fmt.Errorf("Error determining mounter for volume: %s", err.Error()) - return "", c.logger.ErrorRet(err, "getMounterForBackend failed") + return nil, c.logger.ErrorRet(err, "getMounterForBackend failed") } - wwn, ok := mountRequest.Opts["Wwn"] - if !ok { - err = fmt.Errorf("mountRequest.Opts[Wwn] not found") - return "", c.logger.ErrorRet(err, "failed") + return mounter, nil +} + +func (c *Controller) doMount(mountRequest k8sresources.FlexVolumeMountRequest) (string, error) { + defer c.logger.Trace(logs.DEBUG)() + + // Support only >=1.6 + if mountRequest.Version == k8sresources.KubernetesVersion_1_5 { + return "", c.logger.ErrorRet(&k8sVersionNotSupported{mountRequest.Version}, "failed") + } + + mounter, err := c.getMounterByPV(mountRequest.MountDevice) + if err != nil { + return "", c.logger.ErrorRet(err, "getMounterByPV failed") + } + + ubMountRequest, err := c.prepareUbiquityMountRequest(mountRequest) + if err != nil { + return "", c.logger.ErrorRet(err, "prepareUbiquityMountRequest failed") } - volumeMountpoint := fmt.Sprintf(resources.PathToMountUbiquityBlockDevices, wwn) - ubMountRequest := resources.MountRequest{Mountpoint: volumeMountpoint, VolumeConfig: volumeConfig} mountpoint, err := mounter.Mount(ubMountRequest) if err != nil { return "", c.logger.ErrorRet(err, "mounter.Mount failed") @@ -417,52 +466,99 @@ func (c *Controller) doMount(mountRequest k8sresources.FlexVolumeMountRequest) ( return mountpoint, nil } +func (c *Controller) getK8sPVDirectoryByBackend(mountedPath string, k8sPVDirectory string) string{ + /* + mountedPath is the original device mountpoint (e.g /ubiquity/) + The function return the k8sPVDirectory based on the backend. + */ + + // TODO route between backend by using the volume backend instead of using /ubiquity hardcoded in the mountpoint + ubiquityMountPrefix := fmt.Sprintf(resources.PathToMountUbiquityBlockDevices, "") + var lnPath string + if strings.HasPrefix(mountedPath, ubiquityMountPrefix) { + lnPath = k8sPVDirectory + } else { + lnPath, _ = path.Split(k8sPVDirectory) // TODO verify why Scale backend use this split? + } + return lnPath +} + + func (c *Controller) doAfterMount(mountRequest k8sresources.FlexVolumeMountRequest, mountedPath string) error { + /* + Create symbolic link instead of the k8s PV directory that will point to the ubiquity mountpoint. + For example(SCBE backend): + k8s PV directory : /var/lib/kubelet/pods/a9671a20-0fd6-11e8-b968-005056a41609/volumes/ibm~ubiquity-k8s-flex/pvc-6811c716-0f43-11e8-b968-005056a41609 + symbolic link should be : /ubiquity/ + Idempotent: + 1. if k8s PV dir not exist, then just create the slink. + 2. if k8s PV dir exist, then delete the dir and create slink instead. + 3. if k8s PV dir is already slink to the right location, skip. + 4. if k8s PV dir is already slink to wrong location, raise error. + 5. else raise error. + Params: + mountedPath : the real mountpoint (e.g: scbe backend its /ubiqutiy/) + mountRequest.MountPath : the PV k8s directory + k8s version support: + k8s version < 1.6 not supported. Note in version <1.6 the attach/mount, + the mountDir (MountPath) is not created trying to do mount and ln will fail because the dir is not found, + so we need to create the directory before continuing) + k8s version >= 1.6 supported. Note in version >=1.6 the kubelet creates a folder as the MountPath, + including the volume name, whenwe try to create the symlink this will fail because the same name exists. + This is why we need to remove it before continuing. + + */ + defer c.logger.Trace(logs.DEBUG)() - var lnPath string + var k8sPVDirectoryPath string var err error - if mountRequest.Version == k8sresources.KubernetesVersion_1_5 { - //For k8s 1.5, by the time we do the attach/mount, the mountDir (MountPath) is not created trying to do mount and ln will fail because the dir is not found, so we need to create the directory before continuing - dir := filepath.Dir(mountRequest.MountPath) - lnPath = mountRequest.MountPath - k8sRequiredMountPoint := path.Join(mountRequest.MountPath, mountRequest.MountDevice) - if _, err = os.Stat(k8sRequiredMountPoint); err != nil { - if os.IsNotExist(err) { - c.logger.Debug("creating volume directory", logs.Args{{"dir", dir}}) - err = os.MkdirAll(dir, 0777) - if err != nil && !os.IsExist(err) { - err = fmt.Errorf("Failed creating volume directory %#v", err) - return c.logger.ErrorRet(err, "failed") - } + k8sPVDirectoryPath = c.getK8sPVDirectoryByBackend(mountedPath, mountRequest.MountPath) + + // Identify the PV directory by using Lstat and then handle all idempotend cases (use Lstat to get the dir or slink detail and not the evaluation of it) + fileInfo, err := c.exec.Lstat(k8sPVDirectoryPath) + if err != nil { + if c.exec.IsNotExist(err) { + // The k8s PV directory not exist (its a rare case and indicate on idempotent flow) + c.logger.Info("PV directory(k8s-mountpoint) nor slink are not exist. Idempotent - skip delete PV directory(k8s-mountpoint).", logs.Args{{"k8s-mountpoint", k8sPVDirectoryPath},{ "should-point-to-mountpoint",mountedPath}}) + c.logger.Info("Creating slink(k8s-mountpoint) that point to mountpoint", logs.Args{{"k8s-mountpoint", k8sPVDirectoryPath},{ "mountpoint",mountedPath}}) + err = c.exec.Symlink(mountedPath, k8sPVDirectoryPath) + if err != nil { + return c.logger.ErrorRet(err, "Controller: failed to create symlink") } - } - } else { - // For k8s 1.6 and later kubelet creates a folder as the MountPath, including the volume name, whenwe try to create the symlink this will fail because the same name exists. This is why we need to remove it before continuing. - ubiquityMountPrefix := fmt.Sprintf(resources.PathToMountUbiquityBlockDevices, "") - if strings.HasPrefix(mountedPath, ubiquityMountPrefix) { - lnPath = mountRequest.MountPath } else { - lnPath, _ = path.Split(mountRequest.MountPath) + // Maybe some permissions issue + return c.logger.ErrorRet(err, "Controller: failed to identify PV directory(k8s-mountpoint)", logs.Args{{"k8s-mountpoint", k8sPVDirectoryPath}}) } - c.logger.Debug("removing folder", logs.Args{{"folder", mountRequest.MountPath}}) - err = os.Remove(mountRequest.MountPath) - if err != nil && !os.IsExist(err) { - err = fmt.Errorf("Failed removing existing volume directory %#v", err) - return c.logger.ErrorRet(err, "failed") + } else if c.exec.IsDir(fileInfo) { + // Positive flow - the k8s-mountpoint should exist in advance and we should delete it in order to create slink instead + c.logger.Debug("As expected the PV directory(k8s-mountpoint) is a directory, so remove it to prepate slink to mountpoint instead", logs.Args{{"k8s-mountpath", k8sPVDirectoryPath}, {"mountpoint", mountedPath}}) + err = c.exec.Remove(k8sPVDirectoryPath) + if err != nil{ + return c.logger.ErrorRet( + &FailRemovePVorigDirError{k8sPVDirectoryPath, err}, + "failed") } - } - - symLinkCommand := "/bin/ln" - args := []string{"-s", mountedPath, lnPath} - c.logger.Debug(fmt.Sprintf("creating slink from %s -> %s", mountedPath, lnPath)) - var stderr bytes.Buffer - cmd := exec.Command(symLinkCommand, args...) - cmd.Stderr = &stderr - err = cmd.Run() - if err != nil { - err = fmt.Errorf("Controller: mount failed to symlink %#v", stderr.String()) - c.logger.ErrorRet(err, "failed") + c.logger.Info("Creating slink(k8s-mountpoint) that point to mountpoint", logs.Args{{"k8s-mountpoint", k8sPVDirectoryPath},{ "mountpoint",mountedPath}}) + err = c.exec.Symlink(mountedPath, k8sPVDirectoryPath) + if err != nil { + return c.logger.ErrorRet(err, "Controller: failed to create symlink") + } + } else if c.exec.IsSlink(fileInfo){ + // Its already slink so check if slink is ok and skip else raise error + evalSlink, err := c.exec.EvalSymlinks(k8sPVDirectoryPath) + if err != nil{ + return c.logger.ErrorRet(err, "Controller: Idempotent - failed eval the slink of PV directory(k8s-mountpoint)", logs.Args{{"k8s-mountpoint", k8sPVDirectoryPath}}) + } + if evalSlink == mountedPath{ + c.logger.Info("PV directory(k8s-mountpoint) is already slink and point to the right mountpoint. Idempotent - skip slink creation.", logs.Args{{"k8s-mountpoint", k8sPVDirectoryPath},{ "mountpoint",mountedPath}}) + } else{ + return c.logger.ErrorRet( + &wrongSlinkError{k8sPVDirectoryPath, mountedPath, evalSlink}, + "failed") + } + } else{ + return c.logger.ErrorRet(&k8sPVDirectoryIsNotDirNorSlinkError{k8sPVDirectoryPath}, "failed") } c.logger.Debug("Volume mounted successfully", logs.Args{{"mountedPath", mountedPath}}) @@ -475,7 +571,9 @@ func (c *Controller) doUnmountScbe(unmountRequest k8sresources.FlexVolumeUnmount pvName := path.Base(unmountRequest.MountPath) getVolumeRequest := resources.GetVolumeRequest{Name: pvName} + volume, err := c.Client.GetVolume(getVolumeRequest) + // TODO idempotent, if volume not exist then log warning and return success mounter, err := c.getMounterForBackend(volume.Backend) if err != nil { err = fmt.Errorf("Error determining mounter for volume: %s", err.Error()) @@ -496,6 +594,7 @@ func (c *Controller) doUnmountScbe(unmountRequest k8sresources.FlexVolumeUnmount } c.logger.Debug(fmt.Sprintf("Removing the slink [%s] to the real mountpoint [%s]", unmountRequest.MountPath, realMountPoint)) + // TODO idempotent, don't fail if slink not exist. But double check its slink, if not then fail with error. err = c.exec.Remove(unmountRequest.MountPath) if err != nil { err = fmt.Errorf("fail to remove slink %s. Error %#v", unmountRequest.MountPath, err) @@ -580,6 +679,11 @@ func (c *Controller) doActivate(activateRequest resources.ActivateRequest) error func (c *Controller) doAttach(attachRequest k8sresources.FlexVolumeAttachRequest) error { defer c.logger.Trace(logs.DEBUG)() + // Support only >=1.6 + if attachRequest.Version == k8sresources.KubernetesVersion_1_5 { + return c.logger.ErrorRet(&k8sVersionNotSupported{attachRequest.Version}, "failed") + } + ubAttachRequest := resources.AttachRequest{Name: attachRequest.Name, Host: getHost(attachRequest.Host)} _, err := c.Client.Attach(ubAttachRequest) if err != nil { @@ -614,7 +718,7 @@ func (c *Controller) doDetach(detachRequest k8sresources.FlexVolumeDetachRequest } } - + // TODO idempotent, don't trigger Detach if host is empty (even after getHostAttached) ubDetachRequest := resources.DetachRequest{Name: detachRequest.Name, Host: host} err := c.Client.Detach(ubDetachRequest) if err != nil { diff --git a/controller/controller_test.go b/controller/controller_test.go index e96349b33..951e8676c 100644 --- a/controller/controller_test.go +++ b/controller/controller_test.go @@ -17,16 +17,15 @@ package controller_test import ( -// "fmt" - "os" - . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" ctl "github.com/IBM/ubiquity-k8s/controller" -// k8sresources "github.com/IBM/ubiquity-k8s/resources" + k8sresources "github.com/IBM/ubiquity-k8s/resources" "github.com/IBM/ubiquity/fakes" "github.com/IBM/ubiquity/resources" + "fmt" + "encoding/json" ) var _ = Describe("Controller", func() { @@ -35,16 +34,26 @@ var _ = Describe("Controller", func() { fakeClient *fakes.FakeStorageClient controller *ctl.Controller fakeExec *fakes.FakeExecutor + fakeMounterFactory *fakes.FakeMounterFactory + fakeMounter *fakes.FakeMounter ubiquityConfig resources.UbiquityPluginConfig + dat map[string]interface{} ) BeforeEach(func() { fakeExec = new(fakes.FakeExecutor) ubiquityConfig = resources.UbiquityPluginConfig{} fakeClient = new(fakes.FakeStorageClient) - controller = ctl.NewControllerWithClient(testLogger, fakeClient, fakeExec) - os.MkdirAll("/tmp/test/mnt2", 0777) + fakeMounterFactory = new(fakes.FakeMounterFactory) + fakeMounter = new(fakes.FakeMounter) + controller = ctl.NewControllerWithClient(testLogger, ubiquityConfig, fakeClient, fakeExec, fakeMounterFactory) + byt := []byte(`{"Wwn":"fake"}`) + if err := json.Unmarshal(byt, &dat); err != nil { + panic(err) + } + }) + Context(".Init", func() { It("does not error when init is successful", func() { @@ -106,6 +115,387 @@ var _ = Describe("Controller", func() { // Expect(fakeClient.RemoveVolumeCallCount()).To(Equal(1)) // }) }) + Context(".Mount", func() { + It("should fail if k8s version < 1.6 (doMount)", func() { + mountRequest := k8sresources.FlexVolumeMountRequest{MountPath: "fake", MountDevice: "pv1", Opts: map[string]string{"Wwn":"fake"}, Version: k8sresources.KubernetesVersion_1_5} + + mountResponse := controller.Mount(mountRequest) + + Expect(mountResponse.Message).To(MatchRegexp(ctl.SupportK8sVesion)) + Expect(mountResponse.Status).To(Equal(ctl.FlexFailureStr)) + Expect(mountResponse.Device).To(Equal("")) + }) + It("should fail in GetVolume if volume not in ubiqutiyDB (doMount)", func() { + fakeClient.GetVolumeReturns(resources.Volume{}, fmt.Errorf("error not found in DB")) + mountRequest := k8sresources.FlexVolumeMountRequest{MountPath: "/pod/pv1", MountDevice: "pv1", Opts: map[string]string{}} + + mountResponse := controller.Mount(mountRequest) + + Expect(fakeClient.GetVolumeCallCount()).To(Equal(1)) + Expect(mountResponse.Message).To(MatchRegexp(".*error not found in DB")) + Expect(mountResponse.Status).To(Equal(ctl.FlexFailureStr)) + Expect(mountResponse.Device).To(Equal("")) + }) + It("should fail if cannot get mounter for the PV (doMount, GetMounterPerBackend)", func() { + errstr := "ERROR backend" + fakeClient.GetVolumeReturns(resources.Volume{Name: "pv1", Backend: "XXX", Mountpoint:"fake"}, nil) + fakeMounterFactory.GetMounterPerBackendReturns(fakeMounter, fmt.Errorf(errstr)) + controller = ctl.NewControllerWithClient(testLogger, ubiquityConfig, fakeClient, fakeExec, fakeMounterFactory) + mountRequest := k8sresources.FlexVolumeMountRequest{MountPath: "/pod/pv1", MountDevice: "pv1", Opts: map[string]string{}} + + mountResponse := controller.Mount(mountRequest) + + Expect(mountResponse.Device).To(Equal("")) + Expect(fakeClient.GetVolumeCallCount()).To(Equal(1)) + Expect(fakeMounterFactory.GetMounterPerBackendCallCount()).To(Equal(1)) + Expect(fakeClient.GetVolumeConfigCallCount()).To(Equal(0)) + Expect(mountResponse.Message).To(MatchRegexp(errstr)) + Expect(mountResponse.Status).To(Equal(ctl.FlexFailureStr)) + }) + It("should fail to prepareUbiquityMountRequest if GetVolumeConfig failed (doMount)", func() { + errstr := "error GetVolumeConfig" + fakeClient.GetVolumeReturns(resources.Volume{Name: "pv1", Backend: "aaaa", Mountpoint:"fake"}, nil) + byt := []byte(`{"":""}`) + var dat map[string]interface{} + if err := json.Unmarshal(byt, &dat); err != nil { + panic(err) + } + fakeClient.GetVolumeConfigReturns(dat, fmt.Errorf(errstr)) + mountRequest := k8sresources.FlexVolumeMountRequest{MountPath: "/pod/pv1", MountDevice: "pv1", Opts: map[string]string{}} + + mountResponse := controller.Mount(mountRequest) + + Expect(fakeClient.GetVolumeCallCount()).To(Equal(1)) + Expect(fakeMounterFactory.GetMounterPerBackendCallCount()).To(Equal(1)) + Expect(fakeClient.GetVolumeConfigCallCount()).To(Equal(1)) + Expect(fakeMounter.MountCallCount()).To(Equal(0)) + Expect(mountResponse.Message).To(MatchRegexp(errstr)) + Expect(mountResponse.Status).To(Equal(ctl.FlexFailureStr)) + }) + It("should fail to prepareUbiquityMountRequest if GetVolumeConfig does not contain Wwn key (doMount)", func() { + fakeClient.GetVolumeReturns(resources.Volume{Name: "pv1", Backend: "scbe", Mountpoint:"fake"}, nil) + byt := []byte(`{"fake":"fake"}`) + var dat map[string]interface{} + if err := json.Unmarshal(byt, &dat); err != nil { + panic(err) + } + fakeClient.GetVolumeConfigReturns(dat, nil) + mountRequest := k8sresources.FlexVolumeMountRequest{MountPath: "/pod/pv1", MountDevice: "pv1", Opts: map[string]string{}} + + mountResponse := controller.Mount(mountRequest) + + Expect(fakeClient.GetVolumeCallCount()).To(Equal(1)) + Expect(fakeMounterFactory.GetMounterPerBackendCallCount()).To(Equal(1)) + Expect(fakeClient.GetVolumeConfigCallCount()).To(Equal(1)) + Expect(fakeMounter.MountCallCount()).To(Equal(0)) + Expect(mountResponse.Message).To(Equal(ctl.MissingWwnMountRequestErrorStr)) + Expect(mountResponse.Status).To(Equal(ctl.FlexFailureStr)) + }) + + It("should fail if mounter.Mount failed (doMount)", func() { + errstr := "TODO set error in mounter" + fakeClient.GetVolumeReturns(resources.Volume{Name: "pv1", Backend: "scbe", Mountpoint:"fake"}, nil) + byt := []byte(`{"Wwn":"fake"}`) + var dat map[string]interface{} + if err := json.Unmarshal(byt, &dat); err != nil { + panic(err) + } + fakeClient.GetVolumeConfigReturns(dat, nil) + fakeMounter.MountReturns("fake device", fmt.Errorf(errstr)) + fakeMounterFactory.GetMounterPerBackendReturns(fakeMounter, nil) + controller = ctl.NewControllerWithClient(testLogger, ubiquityConfig, fakeClient, fakeExec, fakeMounterFactory) + mountRequest := k8sresources.FlexVolumeMountRequest{MountPath: "/pod/pv1", MountDevice: "pv1", Opts: map[string]string{"Wwn":"fake"}} + + mountResponse := controller.Mount(mountRequest) + + Expect(fakeClient.GetVolumeCallCount()).To(Equal(1)) + Expect(fakeClient.GetVolumeConfigCallCount()).To(Equal(1)) + Expect(fakeMounter.MountCallCount()).To(Equal(1)) + Expect(fakeExec.LstatCallCount()).To(Equal(0)) + Expect(mountResponse.Message).To(Equal(errstr)) + Expect(mountResponse.Status).To(Equal(ctl.FlexFailureStr)) + }) + It("should fail to Mount if fail to lstat k8s-mountpoint (doAfterMount)", func() { + errstr := "fakerror" + errstrObj := fmt.Errorf(errstr) + + fakeClient.GetVolumeReturns(resources.Volume{Name: "pv1", Backend: "scbe", Mountpoint:"fake"}, nil) + fakeClient.GetVolumeConfigReturns(dat, nil) + fakeMounter.MountReturns("/ubiquity/wwn1", nil) + fakeMounterFactory.GetMounterPerBackendReturns(fakeMounter, nil) + controller = ctl.NewControllerWithClient(testLogger, ubiquityConfig, fakeClient, fakeExec, fakeMounterFactory) + fakeExec.LstatReturns(nil, errstrObj) + fakeExec.IsNotExistReturns(false) + mountRequest := k8sresources.FlexVolumeMountRequest{MountPath: "/pod/pv1", MountDevice: "pv1", Opts: map[string]string{"Wwn":"fake"}, Version: k8sresources.KubernetesVersion_1_6OrLater} + + mountResponse := controller.Mount(mountRequest) + + Expect(fakeClient.GetVolumeCallCount()).To(Equal(1)) + Expect(fakeClient.GetVolumeConfigCallCount()).To(Equal(1)) + Expect(fakeMounter.MountCallCount()).To(Equal(1)) + Expect(fakeExec.LstatCallCount()).To(Equal(1)) + Expect(fakeExec.IsNotExistCallCount()).To(Equal(1)) + Expect(fakeExec.IsNotExistArgsForCall(0)).To(Equal(errstrObj)) + Expect(fakeExec.IsDirCallCount()).To(Equal(0)) + Expect(mountResponse.Message).To(Equal(errstr)) + Expect(mountResponse.Status).To(Equal(ctl.FlexFailureStr)) + }) + It("should fail to Mount k8s-mountpoint dir not exist(idempotent) but and failed to slink (doAfterMount)", func() { + errstr := "fakerror" + errstrObj := fmt.Errorf(errstr) + + fakeClient.GetVolumeReturns(resources.Volume{Name: "pv1", Backend: "scbe", Mountpoint:"fake"}, nil) + fakeClient.GetVolumeConfigReturns(dat, nil) + fakeMounter.MountReturns("/ubiquity/wwn1", nil) + fakeMounterFactory.GetMounterPerBackendReturns(fakeMounter, nil) + controller = ctl.NewControllerWithClient(testLogger, ubiquityConfig, fakeClient, fakeExec, fakeMounterFactory) + fakeExec.LstatReturns(nil, errstrObj) + fakeExec.IsNotExistReturns(true) + fakeExec.SymlinkReturns(errstrObj) + mountRequest := k8sresources.FlexVolumeMountRequest{MountPath: "/pod/pv1", MountDevice: "pv1", Opts: map[string]string{"Wwn":"fake"}, Version: k8sresources.KubernetesVersion_1_6OrLater} + + mountResponse := controller.Mount(mountRequest) + + Expect(fakeClient.GetVolumeCallCount()).To(Equal(1)) + Expect(fakeClient.GetVolumeConfigCallCount()).To(Equal(1)) + Expect(fakeMounter.MountCallCount()).To(Equal(1)) + Expect(fakeExec.LstatCallCount()).To(Equal(1)) + Expect(fakeExec.IsNotExistCallCount()).To(Equal(1)) + Expect(fakeExec.IsNotExistArgsForCall(0)).To(Equal(errstrObj)) + Expect(fakeExec.IsDirCallCount()).To(Equal(0)) + Expect(mountResponse.Message).To(Equal(errstr)) + Expect(mountResponse.Status).To(Equal(ctl.FlexFailureStr)) + }) + It("should succeed to Mount k8s-mountpoint dir not exist(idempotent) and slink succeed (doAfterMount)", func() { + errstr := "fakerror" + errstrObj := fmt.Errorf(errstr) + + fakeClient.GetVolumeReturns(resources.Volume{Name: "pv1", Backend: "scbe", Mountpoint:"fake"}, nil) + fakeClient.GetVolumeConfigReturns(dat, nil) + mountpoint := "/ubiquity/wwn1" + fakeMounter.MountReturns(mountpoint, nil) + fakeMounterFactory.GetMounterPerBackendReturns(fakeMounter, nil) + controller = ctl.NewControllerWithClient(testLogger, ubiquityConfig, fakeClient, fakeExec, fakeMounterFactory) + fakeExec.LstatReturns(nil, errstrObj) + fakeExec.IsNotExistReturns(true) + fakeExec.SymlinkReturns(nil) + mountRequest := k8sresources.FlexVolumeMountRequest{MountPath: "/pod/pv1", MountDevice: "pv1", Opts: map[string]string{"Wwn":"fake"}, Version: k8sresources.KubernetesVersion_1_6OrLater} + + mountResponse := controller.Mount(mountRequest) + + Expect(fakeClient.GetVolumeCallCount()).To(Equal(1)) + Expect(fakeClient.GetVolumeConfigCallCount()).To(Equal(1)) + Expect(fakeMounter.MountCallCount()).To(Equal(1)) + Expect(fakeExec.LstatCallCount()).To(Equal(1)) + Expect(fakeExec.IsNotExistCallCount()).To(Equal(1)) + Expect(fakeExec.SymlinkCallCount()).To(Equal(1)) + Expect(fakeExec.IsDirCallCount()).To(Equal(0)) + Expect(mountResponse.Message).To(Equal("")) + Expect(mountResponse.Status).To(Equal(ctl.FlexSuccessStr)) + Expect(mountResponse.Device).To(Equal("")) + }) + It("should fail to Mount because fail to Remove the k8s-mountpoint dir (doAfterMount)", func() { + errstr := "fakerror" + errstrObj := fmt.Errorf(errstr) + + fakeClient.GetVolumeReturns(resources.Volume{Name: "pv1", Backend: "scbe", Mountpoint:"fake"}, nil) + fakeClient.GetVolumeConfigReturns(dat, nil) + fakeMounter.MountReturns("/ubiquity/wwn1", nil) + fakeMounterFactory.GetMounterPerBackendReturns(fakeMounter, nil) + controller = ctl.NewControllerWithClient(testLogger, ubiquityConfig, fakeClient, fakeExec, fakeMounterFactory) + mountRequest := k8sresources.FlexVolumeMountRequest{MountPath: "/tmp", MountDevice: "pv1", Opts: map[string]string{"Wwn":"fake"}, Version: k8sresources.KubernetesVersion_1_6OrLater} + fakeExec.LstatReturns(nil, nil) + fakeExec.IsDirReturns(true) + fakeExec.RemoveReturns(errstrObj) + + mountResponse := controller.Mount(mountRequest) + + Expect(fakeClient.GetVolumeCallCount()).To(Equal(1)) + Expect(fakeClient.GetVolumeConfigCallCount()).To(Equal(1)) + Expect(fakeMounter.MountCallCount()).To(Equal(1)) + Expect(fakeExec.LstatCallCount()).To(Equal(1)) + Expect(fakeExec.IsNotExistCallCount()).To(Equal(0)) + Expect(fakeExec.IsDirCallCount()).To(Equal(1)) + Expect(fakeExec.RemoveCallCount()).To(Equal(1)) + Expect(fakeExec.SymlinkCallCount()).To(Equal(0)) + Expect(mountResponse.Message).To(MatchRegexp(ctl.FailRemovePVorigDirErrorStr)) + Expect(mountResponse.Status).To(Equal(ctl.FlexFailureStr)) + }) + It("should fail to Mount because fail to create Symlink after Remove the k8s-mountpoint dir (doAfterMount)", func() { + errstr := "fakerror" + errstrObj := fmt.Errorf(errstr) + + fakeClient.GetVolumeReturns(resources.Volume{Name: "pv1", Backend: "scbe", Mountpoint:"fake"}, nil) + fakeClient.GetVolumeConfigReturns(dat, nil) + fakeMounter.MountReturns("/ubiquity/wwn1", nil) + fakeMounterFactory.GetMounterPerBackendReturns(fakeMounter, nil) + controller = ctl.NewControllerWithClient(testLogger, ubiquityConfig, fakeClient, fakeExec, fakeMounterFactory) + mountRequest := k8sresources.FlexVolumeMountRequest{MountPath: "/tmp", MountDevice: "pv1", Opts: map[string]string{"Wwn":"fake"}, Version: k8sresources.KubernetesVersion_1_6OrLater} + fakeExec.LstatReturns(nil, nil) + fakeExec.IsDirReturns(true) + fakeExec.RemoveReturns(nil) + fakeExec.SymlinkReturns(errstrObj) + + mountResponse := controller.Mount(mountRequest) + + Expect(fakeClient.GetVolumeCallCount()).To(Equal(1)) + Expect(fakeClient.GetVolumeConfigCallCount()).To(Equal(1)) + Expect(fakeMounter.MountCallCount()).To(Equal(1)) + Expect(fakeExec.LstatCallCount()).To(Equal(1)) + Expect(fakeExec.IsNotExistCallCount()).To(Equal(0)) + Expect(fakeExec.IsDirCallCount()).To(Equal(1)) + Expect(fakeExec.RemoveCallCount()).To(Equal(1)) + Expect(fakeExec.SymlinkCallCount()).To(Equal(1)) + Expect(fakeExec.IsSlinkCallCount()).To(Equal(0)) + Expect(mountResponse.Message).To(MatchRegexp(errstr)) + Expect(mountResponse.Status).To(Equal(ctl.FlexFailureStr)) + }) + + It("should fail to Mount because fail to create Symlink after Remove the k8s-mountpoint dir (doAfterMount)", func() { + fakeClient.GetVolumeReturns(resources.Volume{Name: "pv1", Backend: "scbe", Mountpoint:"fake"}, nil) + fakeClient.GetVolumeConfigReturns(dat, nil) + fakeMounter.MountReturns("/ubiquity/wwn1", nil) + fakeMounterFactory.GetMounterPerBackendReturns(fakeMounter, nil) + controller = ctl.NewControllerWithClient(testLogger, ubiquityConfig, fakeClient, fakeExec, fakeMounterFactory) + mountRequest := k8sresources.FlexVolumeMountRequest{MountPath: "/tmp", MountDevice: "pv1", Opts: map[string]string{"Wwn":"fake"}, Version: k8sresources.KubernetesVersion_1_6OrLater} + fakeExec.LstatReturns(nil, nil) + fakeExec.IsDirReturns(true) + fakeExec.RemoveReturns(nil) + fakeExec.SymlinkReturns(nil) + + mountResponse := controller.Mount(mountRequest) + + Expect(fakeClient.GetVolumeCallCount()).To(Equal(1)) + Expect(fakeClient.GetVolumeConfigCallCount()).To(Equal(1)) + Expect(fakeMounter.MountCallCount()).To(Equal(1)) + Expect(fakeExec.LstatCallCount()).To(Equal(1)) + Expect(fakeExec.IsNotExistCallCount()).To(Equal(0)) + Expect(fakeExec.IsDirCallCount()).To(Equal(1)) + Expect(fakeExec.RemoveCallCount()).To(Equal(1)) + Expect(fakeExec.SymlinkCallCount()).To(Equal(1)) + Expect(fakeExec.IsSlinkCallCount()).To(Equal(0)) + Expect(mountResponse.Message).To(Equal("")) + Expect(mountResponse.Status).To(Equal(ctl.FlexSuccessStr)) + }) + + It("should fail to Mount because fail to EvalSymlinks (idempotent) (doAfterMount)", func() { + errstr := "fakerror" + errstrObj := fmt.Errorf(errstr) + + fakeClient.GetVolumeReturns(resources.Volume{Name: "pv1", Backend: "scbe", Mountpoint:"fake"}, nil) + fakeClient.GetVolumeConfigReturns(dat, nil) + fakeMounter.MountReturns("/ubiquity/wwn1", nil) + fakeMounterFactory.GetMounterPerBackendReturns(fakeMounter, nil) + controller = ctl.NewControllerWithClient(testLogger, ubiquityConfig, fakeClient, fakeExec, fakeMounterFactory) + mountRequest := k8sresources.FlexVolumeMountRequest{MountPath: "/tmp", MountDevice: "pv1", Opts: map[string]string{"Wwn":"fake"}, Version: k8sresources.KubernetesVersion_1_6OrLater} + fakeExec.LstatReturns(nil, nil) + fakeExec.IsDirReturns(false) + fakeExec.IsSlinkReturns(true) + fakeExec.EvalSymlinksReturns("", errstrObj) + + mountResponse := controller.Mount(mountRequest) + + Expect(fakeClient.GetVolumeCallCount()).To(Equal(1)) + Expect(fakeClient.GetVolumeConfigCallCount()).To(Equal(1)) + Expect(fakeMounter.MountCallCount()).To(Equal(1)) + Expect(fakeExec.LstatCallCount()).To(Equal(1)) + Expect(fakeExec.IsNotExistCallCount()).To(Equal(0)) + Expect(fakeExec.IsDirCallCount()).To(Equal(1)) + Expect(fakeExec.IsSlinkCallCount()).To(Equal(1)) + Expect(fakeExec.EvalSymlinksCallCount()).To(Equal(1)) + Expect(mountResponse.Message).To(Equal(errstr)) + Expect(mountResponse.Status).To(Equal(ctl.FlexFailureStr)) + }) + It("should succeed to Mount after k8s-mountpoint is already slink(idempotent) and point to the right mountpath (doAfterMount)", func() { + fakeClient.GetVolumeReturns(resources.Volume{Name: "pv1", Backend: "scbe", Mountpoint:"fake"}, nil) + fakeClient.GetVolumeConfigReturns(dat, nil) + mountPath := "/ubiquity/wwn1" + + fakeMounter.MountReturns(mountPath, nil) + fakeMounterFactory.GetMounterPerBackendReturns(fakeMounter, nil) + controller = ctl.NewControllerWithClient(testLogger, ubiquityConfig, fakeClient, fakeExec, fakeMounterFactory) + mountRequest := k8sresources.FlexVolumeMountRequest{MountPath: "/pod/pv1", MountDevice: "pv1", Opts: map[string]string{"Wwn":"fake"}, Version: k8sresources.KubernetesVersion_1_6OrLater} + fakeExec.LstatReturns(nil, nil) + fakeExec.IsDirReturns(false) + fakeExec.IsSlinkReturns(true) + fakeExec.EvalSymlinksReturns(mountPath, nil) + + mountResponse := controller.Mount(mountRequest) + + Expect(fakeClient.GetVolumeCallCount()).To(Equal(1)) + Expect(fakeClient.GetVolumeConfigCallCount()).To(Equal(1)) + Expect(fakeMounter.MountCallCount()).To(Equal(1)) + Expect(fakeExec.LstatCallCount()).To(Equal(1)) + Expect(fakeExec.IsNotExistCallCount()).To(Equal(0)) + Expect(fakeExec.IsDirCallCount()).To(Equal(1)) + Expect(fakeExec.IsSlinkCallCount()).To(Equal(1)) + Expect(fakeExec.EvalSymlinksCallCount()).To(Equal(1)) + Expect(mountResponse.Message).To(Equal("")) + Expect(mountResponse.Status).To(Equal(ctl.FlexSuccessStr)) + Expect(mountResponse.Device).To(Equal("")) + }) + + It("should fail to Mount after k8s-mountpoint is already slink(idempotent) but point to wrong mountpath (doAfterMount)", func() { + fakeClient.GetVolumeReturns(resources.Volume{Name: "pv1", Backend: "scbe", Mountpoint:"fake"}, nil) + fakeClient.GetVolumeConfigReturns(dat, nil) + mountPath := "/ubiquity/wwn1" + + fakeMounter.MountReturns(mountPath, nil) + fakeMounterFactory.GetMounterPerBackendReturns(fakeMounter, nil) + controller = ctl.NewControllerWithClient(testLogger, ubiquityConfig, fakeClient, fakeExec, fakeMounterFactory) + mountRequest := k8sresources.FlexVolumeMountRequest{MountPath: "/pod/pv1", MountDevice: "pv1", Opts: map[string]string{"Wwn":"fake"}, Version: k8sresources.KubernetesVersion_1_6OrLater} + fakeExec.LstatReturns(nil, nil) + fakeExec.IsDirReturns(false) + fakeExec.IsSlinkReturns(true) + badMountPointForSlink := mountPath + "/bad" + fakeExec.EvalSymlinksReturns(badMountPointForSlink, nil) + + mountResponse := controller.Mount(mountRequest) + + Expect(fakeClient.GetVolumeCallCount()).To(Equal(1)) + Expect(fakeClient.GetVolumeConfigCallCount()).To(Equal(1)) + Expect(fakeMounter.MountCallCount()).To(Equal(1)) + Expect(fakeExec.LstatCallCount()).To(Equal(1)) + Expect(fakeExec.IsNotExistCallCount()).To(Equal(0)) + Expect(fakeExec.IsDirCallCount()).To(Equal(1)) + Expect(fakeExec.IsSlinkCallCount()).To(Equal(1)) + Expect(fakeExec.EvalSymlinksCallCount()).To(Equal(1)) + Expect(mountResponse.Message).To(MatchRegexp(ctl.WrongSlinkErrorStr)) + Expect(mountResponse.Status).To(Equal(ctl.FlexFailureStr)) + }) + It("should fail to Mount when k8s-mountpoint exist but not as dir nor as slink (idempotent) (doAfterMount)", func() { + fakeClient.GetVolumeReturns(resources.Volume{Name: "pv1", Backend: "scbe", Mountpoint:"fake"}, nil) + fakeClient.GetVolumeConfigReturns(dat, nil) + mountPath := "/ubiquity/wwn1" + + fakeMounter.MountReturns(mountPath, nil) + fakeMounterFactory.GetMounterPerBackendReturns(fakeMounter, nil) + controller = ctl.NewControllerWithClient(testLogger, ubiquityConfig, fakeClient, fakeExec, fakeMounterFactory) + mountRequest := k8sresources.FlexVolumeMountRequest{MountPath: "/pod/pv1", MountDevice: "pv1", Opts: map[string]string{"Wwn":"fake"}, Version: k8sresources.KubernetesVersion_1_6OrLater} + fakeExec.LstatReturns(nil, nil) + fakeExec.IsDirReturns(false) + fakeExec.IsSlinkReturns(false) + + mountResponse := controller.Mount(mountRequest) + + Expect(fakeClient.GetVolumeCallCount()).To(Equal(1)) + Expect(fakeClient.GetVolumeConfigCallCount()).To(Equal(1)) + Expect(fakeMounter.MountCallCount()).To(Equal(1)) + Expect(fakeExec.LstatCallCount()).To(Equal(1)) + Expect(fakeExec.IsNotExistCallCount()).To(Equal(0)) + Expect(fakeExec.IsDirCallCount()).To(Equal(1)) + Expect(fakeExec.IsSlinkCallCount()).To(Equal(1)) + Expect(fakeExec.EvalSymlinksCallCount()).To(Equal(0)) + Expect(mountResponse.Message).To(MatchRegexp(ctl.K8sPVDirectoryIsNotDirNorSlinkErrorStr)) + Expect(mountResponse.Status).To(Equal(ctl.FlexFailureStr)) + }) + + + + + + }) + /* Context(".Mount", func() { AfterEach(func() { diff --git a/controller/errors.go b/controller/errors.go new file mode 100644 index 000000000..f9fa7fb24 --- /dev/null +++ b/controller/errors.go @@ -0,0 +1,72 @@ +/** + * Copyright 2018 IBM Corp. + * + * 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 controller + +import ( + "fmt" +) + +// TODO need to remove this error, since its moved to ubiquity it self +type NoMounterForVolumeError struct { + mounter string +} + +func (e *NoMounterForVolumeError) Error() string { + return fmt.Sprintf("Mounter not found for backend: %s", e.mounter) +} + +const MissingWwnMountRequestErrorStr = "volume related to scbe backend must have mountRequest.Opts[Wwn] not found (expect to have wwn for scbe backend volume type)" + +const FailRemovePVorigDirErrorStr = "Failed removing existing volume directory" +type FailRemovePVorigDirError struct { + err string + dir error +} + +func (e *FailRemovePVorigDirError) Error() string { + return fmt.Sprintf(FailRemovePVorigDirErrorStr + ". dir=[%s], err=[%#v]", e.dir, e.err) +} + +const WrongSlinkErrorStr = "Idempotent - The existing slink point to a wrong mountpoint." +type wrongSlinkError struct { + slink string + wrongPointTo string + expectedPointTo string +} + +func (e *wrongSlinkError) Error() string { + return fmt.Sprintf(WrongSlinkErrorStr + " slink=[%s] expected-mountpoint=[%s], wrong-mountpoint=[%s]", e.slink, e.expectedPointTo, e.wrongPointTo) +} + +const SupportK8sVesion = "Support only k8s version >= 1.6." +type k8sVersionNotSupported struct { + version string +} + +func (e *k8sVersionNotSupported) Error() string { + return fmt.Sprintf(SupportK8sVesion + " Version [%s] is not supported.", e.version) +} + +const K8sPVDirectoryIsNotDirNorSlinkErrorStr = "k8s PV directory, k8s-mountpoint, is not a directory nor slink." +type k8sPVDirectoryIsNotDirNorSlinkError struct { + slink string +} + +func (e *k8sPVDirectoryIsNotDirNorSlinkError) Error() string { + return fmt.Sprintf(K8sPVDirectoryIsNotDirNorSlinkErrorStr + " slink=[%s]", e.slink) +} + diff --git a/glide.yaml b/glide.yaml index c140f9c6f..ce2a60694 100644 --- a/glide.yaml +++ b/glide.yaml @@ -9,10 +9,12 @@ import: subpackages: - lib - package: github.com/IBM/ubiquity + version: fix/idempotent_issues_in_umount subpackages: - remote - resources - utils + - fakes - package: k8s.io/apimachinery version: release-1.8 subpackages: diff --git a/volume/provision.go b/volume/provision.go index 3b9663b3a..bd8f21dec 100644 --- a/volume/provision.go +++ b/volume/provision.go @@ -172,6 +172,10 @@ func (p *flexProvisioner) Provision(options controller.VolumeOptions) (*v1.Persi // Delete removes the directory that was created by Provision backing the given // PV. func (p *flexProvisioner) Delete(volume *v1.PersistentVolume) error { + msg := fmt.Sprintf("Delete volume name [%s]", volume.Name) + p.logger.Printf("ENTER : " + msg) + defer p.logger.Printf("EXIT : " + msg) + if volume.Name == "" { return fmt.Errorf("volume name cannot be empty %#v", volume) } @@ -196,6 +200,10 @@ func (p *flexProvisioner) Delete(volume *v1.PersistentVolume) error { } func (p *flexProvisioner) createVolume(options controller.VolumeOptions, capacity int64) (map[string]string, error) { + msg := fmt.Sprintf("Create volume name [%s]", options.PVName) + p.logger.Printf("ENTER : " + msg) + defer p.logger.Printf("EXIT : " + msg) + ubiquityParams := make(map[string]interface{}) if capacity != 0 { ubiquityParams["quota"] = fmt.Sprintf("%dM", capacity) // SSc backend expect quota option From 96ae20eb72f78e8b9227c068c661d33c31f00eb5 Mon Sep 17 00:00:00 2001 From: Shay Berman Date: Wed, 28 Mar 2018 17:31:30 +0300 Subject: [PATCH 02/40] glide update to use ubiquity dev branch --- glide.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/glide.yaml b/glide.yaml index ce2a60694..246a69d54 100644 --- a/glide.yaml +++ b/glide.yaml @@ -9,7 +9,7 @@ import: subpackages: - lib - package: github.com/IBM/ubiquity - version: fix/idempotent_issues_in_umount + version: dev subpackages: - remote - resources From ac72ec83dbf90ead5e196abcd69392348f1295cf Mon Sep 17 00:00:00 2001 From: Shay Berman Date: Sun, 29 Apr 2018 16:37:56 +0300 Subject: [PATCH 03/40] Fix typo in debug message & positional arguments in error (Dana review) --- controller/controller.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/controller/controller.go b/controller/controller.go index db664c965..bb64afc60 100644 --- a/controller/controller.go +++ b/controller/controller.go @@ -532,7 +532,7 @@ func (c *Controller) doAfterMount(mountRequest k8sresources.FlexVolumeMountReque } } else if c.exec.IsDir(fileInfo) { // Positive flow - the k8s-mountpoint should exist in advance and we should delete it in order to create slink instead - c.logger.Debug("As expected the PV directory(k8s-mountpoint) is a directory, so remove it to prepate slink to mountpoint instead", logs.Args{{"k8s-mountpath", k8sPVDirectoryPath}, {"mountpoint", mountedPath}}) + c.logger.Debug("As expected the PV directory(k8s-mountpoint) is a directory, so remove it to prepare slink to mountpoint instead", logs.Args{{"k8s-mountpath", k8sPVDirectoryPath}, {"mountpoint", mountedPath}}) err = c.exec.Remove(k8sPVDirectoryPath) if err != nil{ return c.logger.ErrorRet( @@ -554,7 +554,7 @@ func (c *Controller) doAfterMount(mountRequest k8sresources.FlexVolumeMountReque c.logger.Info("PV directory(k8s-mountpoint) is already slink and point to the right mountpoint. Idempotent - skip slink creation.", logs.Args{{"k8s-mountpoint", k8sPVDirectoryPath},{ "mountpoint",mountedPath}}) } else{ return c.logger.ErrorRet( - &wrongSlinkError{k8sPVDirectoryPath, mountedPath, evalSlink}, + &wrongSlinkError{slink: k8sPVDirectoryPath, wrongPointTo: evalSlink, expectedPointTo: mountedPath}, "failed") } } else{ From 10a4347619e341215c8d84738ac99311bba41aaa Mon Sep 17 00:00:00 2001 From: Shay Berman Date: Wed, 9 May 2018 11:51:08 +0300 Subject: [PATCH 04/40] Apply gofmt fixes --- cmd/flex/main/cli.go | 6 +- cmd/provisioner/main/main.go | 1 - controller/controller.go | 266 ++++++++++++----------- controller/controller_test.go | 385 +++++++++++++++++----------------- controller/errors.go | 17 +- resources/resources.go | 1 + 6 files changed, 333 insertions(+), 343 deletions(-) diff --git a/cmd/flex/main/cli.go b/cmd/flex/main/cli.go index ddfc43c4c..4f525db75 100644 --- a/cmd/flex/main/cli.go +++ b/cmd/flex/main/cli.go @@ -28,8 +28,8 @@ import ( flags "github.com/jessevdk/go-flags" k8sresources "github.com/IBM/ubiquity-k8s/resources" - "github.com/IBM/ubiquity/resources" "github.com/IBM/ubiquity/remote" + "github.com/IBM/ubiquity/resources" "github.com/IBM/ubiquity/utils" "github.com/IBM/ubiquity/utils/logs" "strconv" @@ -567,8 +567,8 @@ func readConfig(configFile string) (resources.UbiquityPluginConfig, error) { } // Create environment variables for some of the config params - os.Setenv(remote.KeyUseSsl, strconv.FormatBool(config.SslConfig.UseSsl)) - os.Setenv(resources.KeySslMode, config.SslConfig.SslMode) + os.Setenv(remote.KeyUseSsl, strconv.FormatBool(config.SslConfig.UseSsl)) + os.Setenv(resources.KeySslMode, config.SslConfig.SslMode) os.Setenv(remote.KeyVerifyCA, config.SslConfig.VerifyCa) return config, nil } diff --git a/cmd/provisioner/main/main.go b/cmd/provisioner/main/main.go index 1204beeb5..f6b7c1ba8 100644 --- a/cmd/provisioner/main/main.go +++ b/cmd/provisioner/main/main.go @@ -100,4 +100,3 @@ func main() { pc := controller.NewProvisionController(clientset, provisioner, flexProvisioner, serverVersion.GitVersion) pc.Run(wait.NeverStop) } - diff --git a/controller/controller.go b/controller/controller.go index bb64afc60..a4f7c96db 100644 --- a/controller/controller.go +++ b/controller/controller.go @@ -18,19 +18,19 @@ package controller import ( "fmt" + "github.com/IBM/ubiquity/utils/logs" "log" "os" "path" "strings" - "github.com/IBM/ubiquity/utils/logs" k8sresources "github.com/IBM/ubiquity-k8s/resources" "github.com/IBM/ubiquity/remote" + "github.com/IBM/ubiquity/remote/mounter" "github.com/IBM/ubiquity/resources" "github.com/IBM/ubiquity/utils" - "path/filepath" - "github.com/IBM/ubiquity/remote/mounter" "github.com/nightlyone/lockfile" + "path/filepath" "time" ) @@ -39,14 +39,14 @@ const FlexFailureStr = "Failure" //Controller this is a structure that controls volume management type Controller struct { - Client resources.StorageClient - exec utils.Executor - logger logs.Logger - legacyLogger *log.Logger - config resources.UbiquityPluginConfig + Client resources.StorageClient + exec utils.Executor + logger logs.Logger + legacyLogger *log.Logger + config resources.UbiquityPluginConfig mounterPerBackend map[string]resources.Mounter - unmountFlock lockfile.Lockfile - mounterFactory mounter.MounterFactory + unmountFlock lockfile.Lockfile + mounterFactory mounter.MounterFactory } //NewController allows to instantiate a controller @@ -61,19 +61,17 @@ func NewController(logger *log.Logger, config resources.UbiquityPluginConfig) (* return nil, err } return &Controller{ - logger: logs.GetLogger(), - legacyLogger: logger, - Client: remoteClient, - exec: utils.NewExecutor(), - config: config, + logger: logs.GetLogger(), + legacyLogger: logger, + Client: remoteClient, + exec: utils.NewExecutor(), + config: config, mounterPerBackend: make(map[string]resources.Mounter), - unmountFlock: unmountFlock, - mounterFactory: mounter.NewMounterFactory(), + unmountFlock: unmountFlock, + mounterFactory: mounter.NewMounterFactory(), }, nil } - - //NewControllerWithClient is made for unit testing purposes where we can pass a fake client func NewControllerWithClient(logger *log.Logger, config resources.UbiquityPluginConfig, client resources.StorageClient, exec utils.Executor, mFactory mounter.MounterFactory) *Controller { unmountFlock, err := lockfile.New(filepath.Join(os.TempDir(), "ubiquity.unmount.lock")) @@ -82,19 +80,17 @@ func NewControllerWithClient(logger *log.Logger, config resources.UbiquityPlugin } return &Controller{ - logger: logs.GetLogger(), - legacyLogger: logger, - Client: client, - exec: exec, - config: config, + logger: logs.GetLogger(), + legacyLogger: logger, + Client: client, + exec: exec, + config: config, mounterPerBackend: make(map[string]resources.Mounter), - unmountFlock: unmountFlock, - mounterFactory: mFactory, + unmountFlock: unmountFlock, + mounterFactory: mFactory, } } - - //Init method is to initialize the k8sresourcesvolume func (c *Controller) Init(config resources.UbiquityPluginConfig) k8sresources.FlexVolumeResponse { defer c.logger.Trace(logs.DEBUG)() @@ -156,7 +152,6 @@ func (c *Controller) Attach(attachRequest k8sresources.FlexVolumeAttachRequest) return response } - //GetVolumeName checks if volume is attached func (c *Controller) GetVolumeName(getVolumeNameRequest k8sresources.FlexVolumeGetVolumeNameRequest) k8sresources.FlexVolumeResponse { defer c.logger.Trace(logs.DEBUG)() @@ -200,7 +195,7 @@ func (c *Controller) IsAttached(isAttachedRequest k8sresources.FlexVolumeIsAttac } } else { response = k8sresources.FlexVolumeResponse{ - Status: "Success", + Status: "Success", Attached: isAttached, } } @@ -310,7 +305,7 @@ func (c *Controller) Unmount(unmountRequest k8sresources.FlexVolumeUnmountReques break } c.logger.Debug("unmountFlock.TryLock failed", logs.Args{{"error", err}}) - time.Sleep(time.Duration(500*time.Millisecond)) + time.Sleep(time.Duration(500 * time.Millisecond)) } c.logger.Debug("Got unmountFlock for mountpath", logs.Args{{"mountpath", unmountRequest.MountPath}}) defer c.unmountFlock.Unlock() @@ -362,7 +357,7 @@ func (c *Controller) Unmount(unmountRequest k8sresources.FlexVolumeUnmountReques return response } -func (c *Controller) doLegacyDetach(unmountRequest k8sresources.FlexVolumeUnmountRequest) error { +func (c *Controller) doLegacyDetach(unmountRequest k8sresources.FlexVolumeUnmountRequest) error { defer c.logger.Trace(logs.DEBUG)() var err error @@ -398,11 +393,10 @@ func (c *Controller) getMounterForBackend(backend string) (resources.Mounter, er return c.mounterPerBackend[backend], nil } - func (c *Controller) prepareUbiquityMountRequest(mountRequest k8sresources.FlexVolumeMountRequest) (resources.MountRequest, error) { /* - Prepare the mounter.Mount request - */ + Prepare the mounter.Mount request + */ defer c.logger.Trace(logs.DEBUG)() // Prepare request for mounter - step1 get volume's config from ubiquity @@ -466,7 +460,7 @@ func (c *Controller) doMount(mountRequest k8sresources.FlexVolumeMountRequest) ( return mountpoint, nil } -func (c *Controller) getK8sPVDirectoryByBackend(mountedPath string, k8sPVDirectory string) string{ +func (c *Controller) getK8sPVDirectoryByBackend(mountedPath string, k8sPVDirectory string) string { /* mountedPath is the original device mountpoint (e.g /ubiquity/) The function return the k8sPVDirectory based on the backend. @@ -483,31 +477,30 @@ func (c *Controller) getK8sPVDirectoryByBackend(mountedPath string, k8sPVDirecto return lnPath } - func (c *Controller) doAfterMount(mountRequest k8sresources.FlexVolumeMountRequest, mountedPath string) error { /* - Create symbolic link instead of the k8s PV directory that will point to the ubiquity mountpoint. - For example(SCBE backend): - k8s PV directory : /var/lib/kubelet/pods/a9671a20-0fd6-11e8-b968-005056a41609/volumes/ibm~ubiquity-k8s-flex/pvc-6811c716-0f43-11e8-b968-005056a41609 - symbolic link should be : /ubiquity/ - Idempotent: - 1. if k8s PV dir not exist, then just create the slink. - 2. if k8s PV dir exist, then delete the dir and create slink instead. - 3. if k8s PV dir is already slink to the right location, skip. - 4. if k8s PV dir is already slink to wrong location, raise error. - 5. else raise error. - Params: - mountedPath : the real mountpoint (e.g: scbe backend its /ubiqutiy/) - mountRequest.MountPath : the PV k8s directory - k8s version support: - k8s version < 1.6 not supported. Note in version <1.6 the attach/mount, - the mountDir (MountPath) is not created trying to do mount and ln will fail because the dir is not found, - so we need to create the directory before continuing) - k8s version >= 1.6 supported. Note in version >=1.6 the kubelet creates a folder as the MountPath, - including the volume name, whenwe try to create the symlink this will fail because the same name exists. - This is why we need to remove it before continuing. - - */ + Create symbolic link instead of the k8s PV directory that will point to the ubiquity mountpoint. + For example(SCBE backend): + k8s PV directory : /var/lib/kubelet/pods/a9671a20-0fd6-11e8-b968-005056a41609/volumes/ibm~ubiquity-k8s-flex/pvc-6811c716-0f43-11e8-b968-005056a41609 + symbolic link should be : /ubiquity/ + Idempotent: + 1. if k8s PV dir not exist, then just create the slink. + 2. if k8s PV dir exist, then delete the dir and create slink instead. + 3. if k8s PV dir is already slink to the right location, skip. + 4. if k8s PV dir is already slink to wrong location, raise error. + 5. else raise error. + Params: + mountedPath : the real mountpoint (e.g: scbe backend its /ubiqutiy/) + mountRequest.MountPath : the PV k8s directory + k8s version support: + k8s version < 1.6 not supported. Note in version <1.6 the attach/mount, + the mountDir (MountPath) is not created trying to do mount and ln will fail because the dir is not found, + so we need to create the directory before continuing) + k8s version >= 1.6 supported. Note in version >=1.6 the kubelet creates a folder as the MountPath, + including the volume name, whenwe try to create the symlink this will fail because the same name exists. + This is why we need to remove it before continuing. + + */ defer c.logger.Trace(logs.DEBUG)() var k8sPVDirectoryPath string @@ -520,8 +513,8 @@ func (c *Controller) doAfterMount(mountRequest k8sresources.FlexVolumeMountReque if err != nil { if c.exec.IsNotExist(err) { // The k8s PV directory not exist (its a rare case and indicate on idempotent flow) - c.logger.Info("PV directory(k8s-mountpoint) nor slink are not exist. Idempotent - skip delete PV directory(k8s-mountpoint).", logs.Args{{"k8s-mountpoint", k8sPVDirectoryPath},{ "should-point-to-mountpoint",mountedPath}}) - c.logger.Info("Creating slink(k8s-mountpoint) that point to mountpoint", logs.Args{{"k8s-mountpoint", k8sPVDirectoryPath},{ "mountpoint",mountedPath}}) + c.logger.Info("PV directory(k8s-mountpoint) nor slink are not exist. Idempotent - skip delete PV directory(k8s-mountpoint).", logs.Args{{"k8s-mountpoint", k8sPVDirectoryPath}, {"should-point-to-mountpoint", mountedPath}}) + c.logger.Info("Creating slink(k8s-mountpoint) that point to mountpoint", logs.Args{{"k8s-mountpoint", k8sPVDirectoryPath}, {"mountpoint", mountedPath}}) err = c.exec.Symlink(mountedPath, k8sPVDirectoryPath) if err != nil { return c.logger.ErrorRet(err, "Controller: failed to create symlink") @@ -534,30 +527,30 @@ func (c *Controller) doAfterMount(mountRequest k8sresources.FlexVolumeMountReque // Positive flow - the k8s-mountpoint should exist in advance and we should delete it in order to create slink instead c.logger.Debug("As expected the PV directory(k8s-mountpoint) is a directory, so remove it to prepare slink to mountpoint instead", logs.Args{{"k8s-mountpath", k8sPVDirectoryPath}, {"mountpoint", mountedPath}}) err = c.exec.Remove(k8sPVDirectoryPath) - if err != nil{ + if err != nil { return c.logger.ErrorRet( &FailRemovePVorigDirError{k8sPVDirectoryPath, err}, "failed") } - c.logger.Info("Creating slink(k8s-mountpoint) that point to mountpoint", logs.Args{{"k8s-mountpoint", k8sPVDirectoryPath},{ "mountpoint",mountedPath}}) + c.logger.Info("Creating slink(k8s-mountpoint) that point to mountpoint", logs.Args{{"k8s-mountpoint", k8sPVDirectoryPath}, {"mountpoint", mountedPath}}) err = c.exec.Symlink(mountedPath, k8sPVDirectoryPath) if err != nil { return c.logger.ErrorRet(err, "Controller: failed to create symlink") } - } else if c.exec.IsSlink(fileInfo){ + } else if c.exec.IsSlink(fileInfo) { // Its already slink so check if slink is ok and skip else raise error evalSlink, err := c.exec.EvalSymlinks(k8sPVDirectoryPath) - if err != nil{ + if err != nil { return c.logger.ErrorRet(err, "Controller: Idempotent - failed eval the slink of PV directory(k8s-mountpoint)", logs.Args{{"k8s-mountpoint", k8sPVDirectoryPath}}) } - if evalSlink == mountedPath{ - c.logger.Info("PV directory(k8s-mountpoint) is already slink and point to the right mountpoint. Idempotent - skip slink creation.", logs.Args{{"k8s-mountpoint", k8sPVDirectoryPath},{ "mountpoint",mountedPath}}) - } else{ + if evalSlink == mountedPath { + c.logger.Info("PV directory(k8s-mountpoint) is already slink and point to the right mountpoint. Idempotent - skip slink creation.", logs.Args{{"k8s-mountpoint", k8sPVDirectoryPath}, {"mountpoint", mountedPath}}) + } else { return c.logger.ErrorRet( &wrongSlinkError{slink: k8sPVDirectoryPath, wrongPointTo: evalSlink, expectedPointTo: mountedPath}, "failed") } - } else{ + } else { return c.logger.ErrorRet(&k8sPVDirectoryIsNotDirNorSlinkError{k8sPVDirectoryPath}, "failed") } @@ -571,7 +564,6 @@ func (c *Controller) doUnmountScbe(unmountRequest k8sresources.FlexVolumeUnmount pvName := path.Base(unmountRequest.MountPath) getVolumeRequest := resources.GetVolumeRequest{Name: pvName} - volume, err := c.Client.GetVolume(getVolumeRequest) // TODO idempotent, if volume not exist then log warning and return success mounter, err := c.getMounterForBackend(volume.Backend) @@ -605,64 +597,64 @@ func (c *Controller) doUnmountScbe(unmountRequest k8sresources.FlexVolumeUnmount } func (c *Controller) doAfterDetach(detachRequest k8sresources.FlexVolumeDetachRequest) error { - defer c.logger.Trace(logs.DEBUG)() - - getVolumeRequest := resources.GetVolumeRequest{Name: detachRequest.Name} - volume, err := c.Client.GetVolume(getVolumeRequest) - mounter, err := c.getMounterForBackend(volume.Backend) - if err != nil { - err = fmt.Errorf("Error determining mounter for volume: %s", err.Error()) - return c.logger.ErrorRet(err, "failed") - } - - getVolumeConfigRequest := resources.GetVolumeConfigRequest{Name: detachRequest.Name} - volumeConfig, err := c.Client.GetVolumeConfig(getVolumeConfigRequest) - if err != nil { - err = fmt.Errorf("Error for volume: %s", err.Error()) - return c.logger.ErrorRet(err, "Client.GetVolumeConfig failed") - } - - afterDetachRequest := resources.AfterDetachRequest{VolumeConfig: volumeConfig} - if err := mounter.ActionAfterDetach(afterDetachRequest); err != nil { - err = fmt.Errorf("Error execute action after detaching the volume : %#v", err) - return c.logger.ErrorRet(err, "mounter.ActionAfterDetach failed") - } - - return nil + defer c.logger.Trace(logs.DEBUG)() + + getVolumeRequest := resources.GetVolumeRequest{Name: detachRequest.Name} + volume, err := c.Client.GetVolume(getVolumeRequest) + mounter, err := c.getMounterForBackend(volume.Backend) + if err != nil { + err = fmt.Errorf("Error determining mounter for volume: %s", err.Error()) + return c.logger.ErrorRet(err, "failed") + } + + getVolumeConfigRequest := resources.GetVolumeConfigRequest{Name: detachRequest.Name} + volumeConfig, err := c.Client.GetVolumeConfig(getVolumeConfigRequest) + if err != nil { + err = fmt.Errorf("Error for volume: %s", err.Error()) + return c.logger.ErrorRet(err, "Client.GetVolumeConfig failed") + } + + afterDetachRequest := resources.AfterDetachRequest{VolumeConfig: volumeConfig} + if err := mounter.ActionAfterDetach(afterDetachRequest); err != nil { + err = fmt.Errorf("Error execute action after detaching the volume : %#v", err) + return c.logger.ErrorRet(err, "mounter.ActionAfterDetach failed") + } + + return nil } func (c *Controller) doUnmountSsc(unmountRequest k8sresources.FlexVolumeUnmountRequest, realMountPoint string) error { - defer c.logger.Trace(logs.DEBUG)() - - listVolumeRequest := resources.ListVolumesRequest{} - volumes, err := c.Client.ListVolumes(listVolumeRequest) - if err != nil { - err = fmt.Errorf("Error getting the volume list from ubiquity server %#v", err) - return c.logger.ErrorRet(err, "failed") - } - - volume, err := getVolumeForMountpoint(unmountRequest.MountPath, volumes) - if err != nil { - err = fmt.Errorf( - "Error finding the volume with mountpoint [%s] from the list of ubiquity volumes %#v. Error is : %#v", - unmountRequest.MountPath, - volumes, - err) - return c.logger.ErrorRet(err, "failed") - } - - detachRequest := resources.DetachRequest{Name: volume.Name} - err = c.Client.Detach(detachRequest) - if err != nil && err.Error() != "fileset not linked" { - err = fmt.Errorf( - "Failed to unmount volume [%s] on mountpoint [%s]. Error: %#v", - volume.Name, - unmountRequest.MountPath, - err) - return c.logger.ErrorRet(err, "failed") - } - - return nil + defer c.logger.Trace(logs.DEBUG)() + + listVolumeRequest := resources.ListVolumesRequest{} + volumes, err := c.Client.ListVolumes(listVolumeRequest) + if err != nil { + err = fmt.Errorf("Error getting the volume list from ubiquity server %#v", err) + return c.logger.ErrorRet(err, "failed") + } + + volume, err := getVolumeForMountpoint(unmountRequest.MountPath, volumes) + if err != nil { + err = fmt.Errorf( + "Error finding the volume with mountpoint [%s] from the list of ubiquity volumes %#v. Error is : %#v", + unmountRequest.MountPath, + volumes, + err) + return c.logger.ErrorRet(err, "failed") + } + + detachRequest := resources.DetachRequest{Name: volume.Name} + err = c.Client.Detach(detachRequest) + if err != nil && err.Error() != "fileset not linked" { + err = fmt.Errorf( + "Failed to unmount volume [%s] on mountpoint [%s]. Error: %#v", + volume.Name, + unmountRequest.MountPath, + err) + return c.logger.ErrorRet(err, "failed") + } + + return nil } func (c *Controller) doActivate(activateRequest resources.ActivateRequest) error { @@ -699,7 +691,7 @@ func (c *Controller) doDetach(detachRequest k8sresources.FlexVolumeDetachRequest if checkIfAttached { opts := make(map[string]string) opts["volumeName"] = detachRequest.Name - isAttachedRequest := k8sresources.FlexVolumeIsAttachedRequest{Name: "", Host:detachRequest.Host, Opts: opts} + isAttachedRequest := k8sresources.FlexVolumeIsAttachedRequest{Name: "", Host: detachRequest.Host, Opts: opts} isAttached, err := c.doIsAttached(isAttachedRequest) if err != nil { return c.logger.ErrorRet(err, "failed") @@ -775,14 +767,14 @@ func getVolumeForMountpoint(mountpoint string, volumes []resources.Volume) (reso } func getHost(hostRequest string) string { - if hostRequest != "" { - return hostRequest - } - // Only in k8s 1.5 this os.Hostname will happened, - // because in k8s 1.5 the flex CLI doesn't get the host to attach with. TODO consider to refactor to remove support for 1.5 - hostname, err := os.Hostname() - if err != nil { - return "" - } - return hostname -} \ No newline at end of file + if hostRequest != "" { + return hostRequest + } + // Only in k8s 1.5 this os.Hostname will happened, + // because in k8s 1.5 the flex CLI doesn't get the host to attach with. TODO consider to refactor to remove support for 1.5 + hostname, err := os.Hostname() + if err != nil { + return "" + } + return hostname +} diff --git a/controller/controller_test.go b/controller/controller_test.go index 951e8676c..4a1711249 100644 --- a/controller/controller_test.go +++ b/controller/controller_test.go @@ -20,24 +20,24 @@ import ( . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + "encoding/json" + "fmt" ctl "github.com/IBM/ubiquity-k8s/controller" k8sresources "github.com/IBM/ubiquity-k8s/resources" "github.com/IBM/ubiquity/fakes" "github.com/IBM/ubiquity/resources" - "fmt" - "encoding/json" ) var _ = Describe("Controller", func() { var ( - fakeClient *fakes.FakeStorageClient - controller *ctl.Controller - fakeExec *fakes.FakeExecutor + fakeClient *fakes.FakeStorageClient + controller *ctl.Controller + fakeExec *fakes.FakeExecutor fakeMounterFactory *fakes.FakeMounterFactory - fakeMounter *fakes.FakeMounter - ubiquityConfig resources.UbiquityPluginConfig - dat map[string]interface{} + fakeMounter *fakes.FakeMounter + ubiquityConfig resources.UbiquityPluginConfig + dat map[string]interface{} ) BeforeEach(func() { fakeExec = new(fakes.FakeExecutor) @@ -53,7 +53,6 @@ var _ = Describe("Controller", func() { }) - Context(".Init", func() { It("does not error when init is successful", func() { @@ -117,7 +116,7 @@ var _ = Describe("Controller", func() { }) Context(".Mount", func() { It("should fail if k8s version < 1.6 (doMount)", func() { - mountRequest := k8sresources.FlexVolumeMountRequest{MountPath: "fake", MountDevice: "pv1", Opts: map[string]string{"Wwn":"fake"}, Version: k8sresources.KubernetesVersion_1_5} + mountRequest := k8sresources.FlexVolumeMountRequest{MountPath: "fake", MountDevice: "pv1", Opts: map[string]string{"Wwn": "fake"}, Version: k8sresources.KubernetesVersion_1_5} mountResponse := controller.Mount(mountRequest) @@ -138,7 +137,7 @@ var _ = Describe("Controller", func() { }) It("should fail if cannot get mounter for the PV (doMount, GetMounterPerBackend)", func() { errstr := "ERROR backend" - fakeClient.GetVolumeReturns(resources.Volume{Name: "pv1", Backend: "XXX", Mountpoint:"fake"}, nil) + fakeClient.GetVolumeReturns(resources.Volume{Name: "pv1", Backend: "XXX", Mountpoint: "fake"}, nil) fakeMounterFactory.GetMounterPerBackendReturns(fakeMounter, fmt.Errorf(errstr)) controller = ctl.NewControllerWithClient(testLogger, ubiquityConfig, fakeClient, fakeExec, fakeMounterFactory) mountRequest := k8sresources.FlexVolumeMountRequest{MountPath: "/pod/pv1", MountDevice: "pv1", Opts: map[string]string{}} @@ -154,7 +153,7 @@ var _ = Describe("Controller", func() { }) It("should fail to prepareUbiquityMountRequest if GetVolumeConfig failed (doMount)", func() { errstr := "error GetVolumeConfig" - fakeClient.GetVolumeReturns(resources.Volume{Name: "pv1", Backend: "aaaa", Mountpoint:"fake"}, nil) + fakeClient.GetVolumeReturns(resources.Volume{Name: "pv1", Backend: "aaaa", Mountpoint: "fake"}, nil) byt := []byte(`{"":""}`) var dat map[string]interface{} if err := json.Unmarshal(byt, &dat); err != nil { @@ -173,7 +172,7 @@ var _ = Describe("Controller", func() { Expect(mountResponse.Status).To(Equal(ctl.FlexFailureStr)) }) It("should fail to prepareUbiquityMountRequest if GetVolumeConfig does not contain Wwn key (doMount)", func() { - fakeClient.GetVolumeReturns(resources.Volume{Name: "pv1", Backend: "scbe", Mountpoint:"fake"}, nil) + fakeClient.GetVolumeReturns(resources.Volume{Name: "pv1", Backend: "scbe", Mountpoint: "fake"}, nil) byt := []byte(`{"fake":"fake"}`) var dat map[string]interface{} if err := json.Unmarshal(byt, &dat); err != nil { @@ -194,7 +193,7 @@ var _ = Describe("Controller", func() { It("should fail if mounter.Mount failed (doMount)", func() { errstr := "TODO set error in mounter" - fakeClient.GetVolumeReturns(resources.Volume{Name: "pv1", Backend: "scbe", Mountpoint:"fake"}, nil) + fakeClient.GetVolumeReturns(resources.Volume{Name: "pv1", Backend: "scbe", Mountpoint: "fake"}, nil) byt := []byte(`{"Wwn":"fake"}`) var dat map[string]interface{} if err := json.Unmarshal(byt, &dat); err != nil { @@ -204,7 +203,7 @@ var _ = Describe("Controller", func() { fakeMounter.MountReturns("fake device", fmt.Errorf(errstr)) fakeMounterFactory.GetMounterPerBackendReturns(fakeMounter, nil) controller = ctl.NewControllerWithClient(testLogger, ubiquityConfig, fakeClient, fakeExec, fakeMounterFactory) - mountRequest := k8sresources.FlexVolumeMountRequest{MountPath: "/pod/pv1", MountDevice: "pv1", Opts: map[string]string{"Wwn":"fake"}} + mountRequest := k8sresources.FlexVolumeMountRequest{MountPath: "/pod/pv1", MountDevice: "pv1", Opts: map[string]string{"Wwn": "fake"}} mountResponse := controller.Mount(mountRequest) @@ -219,14 +218,14 @@ var _ = Describe("Controller", func() { errstr := "fakerror" errstrObj := fmt.Errorf(errstr) - fakeClient.GetVolumeReturns(resources.Volume{Name: "pv1", Backend: "scbe", Mountpoint:"fake"}, nil) + fakeClient.GetVolumeReturns(resources.Volume{Name: "pv1", Backend: "scbe", Mountpoint: "fake"}, nil) fakeClient.GetVolumeConfigReturns(dat, nil) fakeMounter.MountReturns("/ubiquity/wwn1", nil) fakeMounterFactory.GetMounterPerBackendReturns(fakeMounter, nil) controller = ctl.NewControllerWithClient(testLogger, ubiquityConfig, fakeClient, fakeExec, fakeMounterFactory) fakeExec.LstatReturns(nil, errstrObj) fakeExec.IsNotExistReturns(false) - mountRequest := k8sresources.FlexVolumeMountRequest{MountPath: "/pod/pv1", MountDevice: "pv1", Opts: map[string]string{"Wwn":"fake"}, Version: k8sresources.KubernetesVersion_1_6OrLater} + mountRequest := k8sresources.FlexVolumeMountRequest{MountPath: "/pod/pv1", MountDevice: "pv1", Opts: map[string]string{"Wwn": "fake"}, Version: k8sresources.KubernetesVersion_1_6OrLater} mountResponse := controller.Mount(mountRequest) @@ -244,7 +243,7 @@ var _ = Describe("Controller", func() { errstr := "fakerror" errstrObj := fmt.Errorf(errstr) - fakeClient.GetVolumeReturns(resources.Volume{Name: "pv1", Backend: "scbe", Mountpoint:"fake"}, nil) + fakeClient.GetVolumeReturns(resources.Volume{Name: "pv1", Backend: "scbe", Mountpoint: "fake"}, nil) fakeClient.GetVolumeConfigReturns(dat, nil) fakeMounter.MountReturns("/ubiquity/wwn1", nil) fakeMounterFactory.GetMounterPerBackendReturns(fakeMounter, nil) @@ -252,7 +251,7 @@ var _ = Describe("Controller", func() { fakeExec.LstatReturns(nil, errstrObj) fakeExec.IsNotExistReturns(true) fakeExec.SymlinkReturns(errstrObj) - mountRequest := k8sresources.FlexVolumeMountRequest{MountPath: "/pod/pv1", MountDevice: "pv1", Opts: map[string]string{"Wwn":"fake"}, Version: k8sresources.KubernetesVersion_1_6OrLater} + mountRequest := k8sresources.FlexVolumeMountRequest{MountPath: "/pod/pv1", MountDevice: "pv1", Opts: map[string]string{"Wwn": "fake"}, Version: k8sresources.KubernetesVersion_1_6OrLater} mountResponse := controller.Mount(mountRequest) @@ -270,7 +269,7 @@ var _ = Describe("Controller", func() { errstr := "fakerror" errstrObj := fmt.Errorf(errstr) - fakeClient.GetVolumeReturns(resources.Volume{Name: "pv1", Backend: "scbe", Mountpoint:"fake"}, nil) + fakeClient.GetVolumeReturns(resources.Volume{Name: "pv1", Backend: "scbe", Mountpoint: "fake"}, nil) fakeClient.GetVolumeConfigReturns(dat, nil) mountpoint := "/ubiquity/wwn1" fakeMounter.MountReturns(mountpoint, nil) @@ -279,7 +278,7 @@ var _ = Describe("Controller", func() { fakeExec.LstatReturns(nil, errstrObj) fakeExec.IsNotExistReturns(true) fakeExec.SymlinkReturns(nil) - mountRequest := k8sresources.FlexVolumeMountRequest{MountPath: "/pod/pv1", MountDevice: "pv1", Opts: map[string]string{"Wwn":"fake"}, Version: k8sresources.KubernetesVersion_1_6OrLater} + mountRequest := k8sresources.FlexVolumeMountRequest{MountPath: "/pod/pv1", MountDevice: "pv1", Opts: map[string]string{"Wwn": "fake"}, Version: k8sresources.KubernetesVersion_1_6OrLater} mountResponse := controller.Mount(mountRequest) @@ -298,12 +297,12 @@ var _ = Describe("Controller", func() { errstr := "fakerror" errstrObj := fmt.Errorf(errstr) - fakeClient.GetVolumeReturns(resources.Volume{Name: "pv1", Backend: "scbe", Mountpoint:"fake"}, nil) + fakeClient.GetVolumeReturns(resources.Volume{Name: "pv1", Backend: "scbe", Mountpoint: "fake"}, nil) fakeClient.GetVolumeConfigReturns(dat, nil) fakeMounter.MountReturns("/ubiquity/wwn1", nil) fakeMounterFactory.GetMounterPerBackendReturns(fakeMounter, nil) controller = ctl.NewControllerWithClient(testLogger, ubiquityConfig, fakeClient, fakeExec, fakeMounterFactory) - mountRequest := k8sresources.FlexVolumeMountRequest{MountPath: "/tmp", MountDevice: "pv1", Opts: map[string]string{"Wwn":"fake"}, Version: k8sresources.KubernetesVersion_1_6OrLater} + mountRequest := k8sresources.FlexVolumeMountRequest{MountPath: "/tmp", MountDevice: "pv1", Opts: map[string]string{"Wwn": "fake"}, Version: k8sresources.KubernetesVersion_1_6OrLater} fakeExec.LstatReturns(nil, nil) fakeExec.IsDirReturns(true) fakeExec.RemoveReturns(errstrObj) @@ -325,12 +324,12 @@ var _ = Describe("Controller", func() { errstr := "fakerror" errstrObj := fmt.Errorf(errstr) - fakeClient.GetVolumeReturns(resources.Volume{Name: "pv1", Backend: "scbe", Mountpoint:"fake"}, nil) + fakeClient.GetVolumeReturns(resources.Volume{Name: "pv1", Backend: "scbe", Mountpoint: "fake"}, nil) fakeClient.GetVolumeConfigReturns(dat, nil) fakeMounter.MountReturns("/ubiquity/wwn1", nil) fakeMounterFactory.GetMounterPerBackendReturns(fakeMounter, nil) controller = ctl.NewControllerWithClient(testLogger, ubiquityConfig, fakeClient, fakeExec, fakeMounterFactory) - mountRequest := k8sresources.FlexVolumeMountRequest{MountPath: "/tmp", MountDevice: "pv1", Opts: map[string]string{"Wwn":"fake"}, Version: k8sresources.KubernetesVersion_1_6OrLater} + mountRequest := k8sresources.FlexVolumeMountRequest{MountPath: "/tmp", MountDevice: "pv1", Opts: map[string]string{"Wwn": "fake"}, Version: k8sresources.KubernetesVersion_1_6OrLater} fakeExec.LstatReturns(nil, nil) fakeExec.IsDirReturns(true) fakeExec.RemoveReturns(nil) @@ -352,12 +351,12 @@ var _ = Describe("Controller", func() { }) It("should fail to Mount because fail to create Symlink after Remove the k8s-mountpoint dir (doAfterMount)", func() { - fakeClient.GetVolumeReturns(resources.Volume{Name: "pv1", Backend: "scbe", Mountpoint:"fake"}, nil) + fakeClient.GetVolumeReturns(resources.Volume{Name: "pv1", Backend: "scbe", Mountpoint: "fake"}, nil) fakeClient.GetVolumeConfigReturns(dat, nil) fakeMounter.MountReturns("/ubiquity/wwn1", nil) fakeMounterFactory.GetMounterPerBackendReturns(fakeMounter, nil) controller = ctl.NewControllerWithClient(testLogger, ubiquityConfig, fakeClient, fakeExec, fakeMounterFactory) - mountRequest := k8sresources.FlexVolumeMountRequest{MountPath: "/tmp", MountDevice: "pv1", Opts: map[string]string{"Wwn":"fake"}, Version: k8sresources.KubernetesVersion_1_6OrLater} + mountRequest := k8sresources.FlexVolumeMountRequest{MountPath: "/tmp", MountDevice: "pv1", Opts: map[string]string{"Wwn": "fake"}, Version: k8sresources.KubernetesVersion_1_6OrLater} fakeExec.LstatReturns(nil, nil) fakeExec.IsDirReturns(true) fakeExec.RemoveReturns(nil) @@ -382,12 +381,12 @@ var _ = Describe("Controller", func() { errstr := "fakerror" errstrObj := fmt.Errorf(errstr) - fakeClient.GetVolumeReturns(resources.Volume{Name: "pv1", Backend: "scbe", Mountpoint:"fake"}, nil) + fakeClient.GetVolumeReturns(resources.Volume{Name: "pv1", Backend: "scbe", Mountpoint: "fake"}, nil) fakeClient.GetVolumeConfigReturns(dat, nil) fakeMounter.MountReturns("/ubiquity/wwn1", nil) fakeMounterFactory.GetMounterPerBackendReturns(fakeMounter, nil) controller = ctl.NewControllerWithClient(testLogger, ubiquityConfig, fakeClient, fakeExec, fakeMounterFactory) - mountRequest := k8sresources.FlexVolumeMountRequest{MountPath: "/tmp", MountDevice: "pv1", Opts: map[string]string{"Wwn":"fake"}, Version: k8sresources.KubernetesVersion_1_6OrLater} + mountRequest := k8sresources.FlexVolumeMountRequest{MountPath: "/tmp", MountDevice: "pv1", Opts: map[string]string{"Wwn": "fake"}, Version: k8sresources.KubernetesVersion_1_6OrLater} fakeExec.LstatReturns(nil, nil) fakeExec.IsDirReturns(false) fakeExec.IsSlinkReturns(true) @@ -407,14 +406,14 @@ var _ = Describe("Controller", func() { Expect(mountResponse.Status).To(Equal(ctl.FlexFailureStr)) }) It("should succeed to Mount after k8s-mountpoint is already slink(idempotent) and point to the right mountpath (doAfterMount)", func() { - fakeClient.GetVolumeReturns(resources.Volume{Name: "pv1", Backend: "scbe", Mountpoint:"fake"}, nil) + fakeClient.GetVolumeReturns(resources.Volume{Name: "pv1", Backend: "scbe", Mountpoint: "fake"}, nil) fakeClient.GetVolumeConfigReturns(dat, nil) mountPath := "/ubiquity/wwn1" fakeMounter.MountReturns(mountPath, nil) fakeMounterFactory.GetMounterPerBackendReturns(fakeMounter, nil) controller = ctl.NewControllerWithClient(testLogger, ubiquityConfig, fakeClient, fakeExec, fakeMounterFactory) - mountRequest := k8sresources.FlexVolumeMountRequest{MountPath: "/pod/pv1", MountDevice: "pv1", Opts: map[string]string{"Wwn":"fake"}, Version: k8sresources.KubernetesVersion_1_6OrLater} + mountRequest := k8sresources.FlexVolumeMountRequest{MountPath: "/pod/pv1", MountDevice: "pv1", Opts: map[string]string{"Wwn": "fake"}, Version: k8sresources.KubernetesVersion_1_6OrLater} fakeExec.LstatReturns(nil, nil) fakeExec.IsDirReturns(false) fakeExec.IsSlinkReturns(true) @@ -436,14 +435,14 @@ var _ = Describe("Controller", func() { }) It("should fail to Mount after k8s-mountpoint is already slink(idempotent) but point to wrong mountpath (doAfterMount)", func() { - fakeClient.GetVolumeReturns(resources.Volume{Name: "pv1", Backend: "scbe", Mountpoint:"fake"}, nil) + fakeClient.GetVolumeReturns(resources.Volume{Name: "pv1", Backend: "scbe", Mountpoint: "fake"}, nil) fakeClient.GetVolumeConfigReturns(dat, nil) mountPath := "/ubiquity/wwn1" fakeMounter.MountReturns(mountPath, nil) fakeMounterFactory.GetMounterPerBackendReturns(fakeMounter, nil) controller = ctl.NewControllerWithClient(testLogger, ubiquityConfig, fakeClient, fakeExec, fakeMounterFactory) - mountRequest := k8sresources.FlexVolumeMountRequest{MountPath: "/pod/pv1", MountDevice: "pv1", Opts: map[string]string{"Wwn":"fake"}, Version: k8sresources.KubernetesVersion_1_6OrLater} + mountRequest := k8sresources.FlexVolumeMountRequest{MountPath: "/pod/pv1", MountDevice: "pv1", Opts: map[string]string{"Wwn": "fake"}, Version: k8sresources.KubernetesVersion_1_6OrLater} fakeExec.LstatReturns(nil, nil) fakeExec.IsDirReturns(false) fakeExec.IsSlinkReturns(true) @@ -464,14 +463,14 @@ var _ = Describe("Controller", func() { Expect(mountResponse.Status).To(Equal(ctl.FlexFailureStr)) }) It("should fail to Mount when k8s-mountpoint exist but not as dir nor as slink (idempotent) (doAfterMount)", func() { - fakeClient.GetVolumeReturns(resources.Volume{Name: "pv1", Backend: "scbe", Mountpoint:"fake"}, nil) + fakeClient.GetVolumeReturns(resources.Volume{Name: "pv1", Backend: "scbe", Mountpoint: "fake"}, nil) fakeClient.GetVolumeConfigReturns(dat, nil) mountPath := "/ubiquity/wwn1" fakeMounter.MountReturns(mountPath, nil) fakeMounterFactory.GetMounterPerBackendReturns(fakeMounter, nil) controller = ctl.NewControllerWithClient(testLogger, ubiquityConfig, fakeClient, fakeExec, fakeMounterFactory) - mountRequest := k8sresources.FlexVolumeMountRequest{MountPath: "/pod/pv1", MountDevice: "pv1", Opts: map[string]string{"Wwn":"fake"}, Version: k8sresources.KubernetesVersion_1_6OrLater} + mountRequest := k8sresources.FlexVolumeMountRequest{MountPath: "/pod/pv1", MountDevice: "pv1", Opts: map[string]string{"Wwn": "fake"}, Version: k8sresources.KubernetesVersion_1_6OrLater} fakeExec.LstatReturns(nil, nil) fakeExec.IsDirReturns(false) fakeExec.IsSlinkReturns(false) @@ -490,170 +489,166 @@ var _ = Describe("Controller", func() { Expect(mountResponse.Status).To(Equal(ctl.FlexFailureStr)) }) - - - - }) /* - Context(".Mount", func() { - AfterEach(func() { - - err := os.RemoveAll("/tmp/test/mnt1") - Expect(err).ToNot(HaveOccurred()) - - }) - It("does not error when volume exists and is not currently mounted", func() { - fakeClient.AttachReturns("/tmp/test/mnt1", nil) - - mountRequest := k8sresources.FlexVolumeMountRequest{MountPath: "/tmp/test/mnt2", MountDevice: "vol1", Opts: map[string]string{}} - mountResponse := controller.Mount(mountRequest) - Expect(mountResponse.Message).To(Equal("Volume mounted successfully to /tmp/test/mnt1")) - Expect(mountResponse.Status).To(Equal("Success")) - - Expect(mountResponse.Device).To(Equal("")) - Expect(fakeClient.AttachCallCount()).To(Equal(1)) + Context(".Mount", func() { + AfterEach(func() { + + err := os.RemoveAll("/tmp/test/mnt1") + Expect(err).ToNot(HaveOccurred()) + + }) + It("does not error when volume exists and is not currently mounted", func() { + fakeClient.AttachReturns("/tmp/test/mnt1", nil) + + mountRequest := k8sresources.FlexVolumeMountRequest{MountPath: "/tmp/test/mnt2", MountDevice: "vol1", Opts: map[string]string{}} + mountResponse := controller.Mount(mountRequest) + Expect(mountResponse.Message).To(Equal("Volume mounted successfully to /tmp/test/mnt1")) + Expect(mountResponse.Status).To(Equal("Success")) + + Expect(mountResponse.Device).To(Equal("")) + Expect(fakeClient.AttachCallCount()).To(Equal(1)) + }) + + It("errors when volume exists and client fails to mount it", func() { + err := fmt.Errorf("failed to mount volume") + fakeClient.AttachReturns("", err) + mountRequest := k8sresources.FlexVolumeMountRequest{MountPath: "some-mountpath", MountDevice: "vol1", Opts: map[string]string{}} + mountResponse := controller.Mount(mountRequest) + Expect(mountResponse.Status).To(Equal("Failure")) + Expect(mountResponse.Message).To(MatchRegexp(err.Error())) + Expect(mountResponse.Device).To(Equal("")) + Expect(fakeClient.AttachCallCount()).To(Equal(1)) + }) }) - - It("errors when volume exists and client fails to mount it", func() { - err := fmt.Errorf("failed to mount volume") - fakeClient.AttachReturns("", err) - mountRequest := k8sresources.FlexVolumeMountRequest{MountPath: "some-mountpath", MountDevice: "vol1", Opts: map[string]string{}} - mountResponse := controller.Mount(mountRequest) - Expect(mountResponse.Status).To(Equal("Failure")) - Expect(mountResponse.Message).To(MatchRegexp(err.Error())) - Expect(mountResponse.Device).To(Equal("")) - Expect(fakeClient.AttachCallCount()).To(Equal(1)) + Context(".Unmount", func() { + var volumes []resources.Volume + It("succeeds when volume exists and is currently mounted", func() { + fakeExec.EvalSymlinksReturns("/path/gpfs/fs/mountpoint", nil) + fakeClient.DetachReturns(nil) + volume := resources.Volume{Name: "vol1", Mountpoint: "some-mountpoint"} + volumes = []resources.Volume{volume} + fakeClient.ListVolumesReturns(volumes, nil) + unmountRequest := k8sresources.FlexVolumeUnmountRequest{MountPath: "some-mountpoint"} + unmountResponse := controller.Unmount(unmountRequest) + Expect(unmountResponse.Status).To(Equal("Success")) + Expect(unmountResponse.Message).To(Equal("Volume unmounted successfully")) + Expect(unmountResponse.Device).To(Equal("")) + Expect(fakeClient.DetachCallCount()).To(Equal(1)) + Expect(fakeClient.ListVolumesCallCount()).To(Equal(1)) + }) + It("errors when client fails to get volume related to the mountpoint", func() { + err := fmt.Errorf("failed to get fileset") + fakeClient.ListVolumesReturns(volumes, err) + unmountRequest := k8sresources.FlexVolumeUnmountRequest{MountPath: "some-mountpoint"} + unmountResponse := controller.Unmount(unmountRequest) + + Expect(unmountResponse.Status).To(Equal("Failure")) + Expect(unmountResponse.Message).To(MatchRegexp(err.Error())) + Expect(unmountResponse.Device).To(Equal("")) + Expect(fakeClient.ListVolumesCallCount()).To(Equal(1)) + Expect(fakeClient.DetachCallCount()).To(Equal(0)) + }) + It("errors when volume does not exist", func() { + volumes = []resources.Volume{} + fakeClient.ListVolumesReturns(volumes, nil) + unmountRequest := k8sresources.FlexVolumeUnmountRequest{MountPath: "some-mountpoint"} + unmountResponse := controller.Unmount(unmountRequest) + + Expect(unmountResponse.Status).To(Equal("Failure")) + Expect(unmountResponse.Message).To(MatchRegexp("Volume not found")) + Expect(unmountResponse.Device).To(Equal("")) + Expect(fakeClient.ListVolumesCallCount()).To(Equal(1)) + Expect(fakeClient.DetachCallCount()).To(Equal(0)) + }) + It("errors when volume exists and client fails to unmount it", func() { + err := fmt.Errorf("error detaching the volume") + volume := resources.Volume{Name: "vol1", Mountpoint: "some-mountpoint"} + volumes = []resources.Volume{volume} + fakeClient.ListVolumesReturns(volumes, nil) + fakeClient.DetachReturns(err) + unmountRequest := k8sresources.FlexVolumeUnmountRequest{MountPath: "some-mountpoint"} + unmountResponse := controller.Unmount(unmountRequest) + + Expect(unmountResponse.Status).To(Equal("Failure")) + Expect(unmountResponse.Message).To(MatchRegexp(err.Error())) + Expect(unmountResponse.Device).To(Equal("")) + Expect(fakeClient.ListVolumesCallCount()).To(Equal(1)) + Expect(fakeClient.DetachCallCount()).To(Equal(1)) + + }) + It("should fail to umount if mountpoint is not slink", func() { + errMsg := fmt.Errorf("not a link") + fakeExec.EvalSymlinksReturns("", errMsg) + + unmountRequest := k8sresources.FlexVolumeUnmountRequest{MountPath: "some-mountpoint"} + unmountResponse := controller.Unmount(unmountRequest) + + Expect(unmountResponse.Status).To(Equal("Failure")) + Expect(unmountResponse.Message).To(MatchRegexp(errMsg.Error())) + Expect(unmountResponse.Device).To(Equal("")) + }) + It("should fail to umount if detach failed", func() { + errMsg := fmt.Errorf("error") + realMountPoint := fmt.Sprintf(resources.PathToMountUbiquityBlockDevices, "fakeWWN") + fakeExec.EvalSymlinksReturns(realMountPoint, nil) + fakeClient.DetachReturns(errMsg) + + unmountRequest := k8sresources.FlexVolumeUnmountRequest{MountPath: "/k8s/podid/some/pvname"} + unmountResponse := controller.Unmount(unmountRequest) + Expect(unmountResponse.Status).To(Equal("Failure")) + Expect(unmountResponse.Message).To(MatchRegexp(errMsg.Error())) + Expect(unmountResponse.Device).To(Equal("")) + detachRequest := fakeClient.DetachArgsForCall(0) + Expect(detachRequest.Name).To(Equal("pvname")) + }) + It("should fail to umount if detach failed", func() { + errMsg := fmt.Errorf("error") + realMountPoint := fmt.Sprintf(resources.PathToMountUbiquityBlockDevices, "fakeWWN") + fakeExec.EvalSymlinksReturns(realMountPoint, nil) + fakeClient.DetachReturns(errMsg) + + unmountRequest := k8sresources.FlexVolumeUnmountRequest{MountPath: "/k8s/podid/some/pvname"} + unmountResponse := controller.Unmount(unmountRequest) + Expect(unmountResponse.Status).To(Equal("Failure")) + Expect(unmountResponse.Message).To(MatchRegexp(errMsg.Error())) + Expect(unmountResponse.Device).To(Equal("")) + detachRequest := fakeClient.DetachArgsForCall(0) + Expect(detachRequest.Name).To(Equal("pvname")) + }) + + It("should fail to umount if fail to remove the slink", func() { + errMsg := fmt.Errorf("error") + realMountPoint := fmt.Sprintf(resources.PathToMountUbiquityBlockDevices, "fakeWWN") + fakeExec.EvalSymlinksReturns(realMountPoint, nil) + fakeClient.DetachReturns(nil) + fakeExec.RemoveReturns(errMsg) + + unmountRequest := k8sresources.FlexVolumeUnmountRequest{MountPath: "/k8s/podid/some/pvname"} + unmountResponse := controller.Unmount(unmountRequest) + Expect(unmountResponse.Status).To(Equal("Failure")) + Expect(unmountResponse.Message).To(MatchRegexp(errMsg.Error())) + Expect(unmountResponse.Device).To(Equal("")) + detachRequest := fakeClient.DetachArgsForCall(0) + Expect(detachRequest.Name).To(Equal("pvname")) + Expect(fakeExec.RemoveCallCount()).To(Equal(1)) + }) + It("should succeed to umount if the scbe umount flow finished ok", func() { + realMountPoint := fmt.Sprintf(resources.PathToMountUbiquityBlockDevices, "fakeWWN") + fakeExec.EvalSymlinksReturns(realMountPoint, nil) + fakeClient.DetachReturns(nil) + fakeExec.RemoveReturns(nil) + + unmountRequest := k8sresources.FlexVolumeUnmountRequest{MountPath: "/k8s/podid/some/pvname"} + unmountResponse := controller.Unmount(unmountRequest) + Expect(unmountResponse.Status).To(Equal("Success")) + Expect(unmountResponse.Message).To(Equal("Volume unmounted successfully")) + Expect(unmountResponse.Device).To(Equal("")) + detachRequest := fakeClient.DetachArgsForCall(0) + Expect(detachRequest.Name).To(Equal("pvname")) + Expect(fakeExec.RemoveCallCount()).To(Equal(1)) + }) }) - }) - Context(".Unmount", func() { - var volumes []resources.Volume - It("succeeds when volume exists and is currently mounted", func() { - fakeExec.EvalSymlinksReturns("/path/gpfs/fs/mountpoint", nil) - fakeClient.DetachReturns(nil) - volume := resources.Volume{Name: "vol1", Mountpoint: "some-mountpoint"} - volumes = []resources.Volume{volume} - fakeClient.ListVolumesReturns(volumes, nil) - unmountRequest := k8sresources.FlexVolumeUnmountRequest{MountPath: "some-mountpoint"} - unmountResponse := controller.Unmount(unmountRequest) - Expect(unmountResponse.Status).To(Equal("Success")) - Expect(unmountResponse.Message).To(Equal("Volume unmounted successfully")) - Expect(unmountResponse.Device).To(Equal("")) - Expect(fakeClient.DetachCallCount()).To(Equal(1)) - Expect(fakeClient.ListVolumesCallCount()).To(Equal(1)) - }) - It("errors when client fails to get volume related to the mountpoint", func() { - err := fmt.Errorf("failed to get fileset") - fakeClient.ListVolumesReturns(volumes, err) - unmountRequest := k8sresources.FlexVolumeUnmountRequest{MountPath: "some-mountpoint"} - unmountResponse := controller.Unmount(unmountRequest) - - Expect(unmountResponse.Status).To(Equal("Failure")) - Expect(unmountResponse.Message).To(MatchRegexp(err.Error())) - Expect(unmountResponse.Device).To(Equal("")) - Expect(fakeClient.ListVolumesCallCount()).To(Equal(1)) - Expect(fakeClient.DetachCallCount()).To(Equal(0)) - }) - It("errors when volume does not exist", func() { - volumes = []resources.Volume{} - fakeClient.ListVolumesReturns(volumes, nil) - unmountRequest := k8sresources.FlexVolumeUnmountRequest{MountPath: "some-mountpoint"} - unmountResponse := controller.Unmount(unmountRequest) - - Expect(unmountResponse.Status).To(Equal("Failure")) - Expect(unmountResponse.Message).To(MatchRegexp("Volume not found")) - Expect(unmountResponse.Device).To(Equal("")) - Expect(fakeClient.ListVolumesCallCount()).To(Equal(1)) - Expect(fakeClient.DetachCallCount()).To(Equal(0)) - }) - It("errors when volume exists and client fails to unmount it", func() { - err := fmt.Errorf("error detaching the volume") - volume := resources.Volume{Name: "vol1", Mountpoint: "some-mountpoint"} - volumes = []resources.Volume{volume} - fakeClient.ListVolumesReturns(volumes, nil) - fakeClient.DetachReturns(err) - unmountRequest := k8sresources.FlexVolumeUnmountRequest{MountPath: "some-mountpoint"} - unmountResponse := controller.Unmount(unmountRequest) - - Expect(unmountResponse.Status).To(Equal("Failure")) - Expect(unmountResponse.Message).To(MatchRegexp(err.Error())) - Expect(unmountResponse.Device).To(Equal("")) - Expect(fakeClient.ListVolumesCallCount()).To(Equal(1)) - Expect(fakeClient.DetachCallCount()).To(Equal(1)) - - }) - It("should fail to umount if mountpoint is not slink", func() { - errMsg := fmt.Errorf("not a link") - fakeExec.EvalSymlinksReturns("", errMsg) - - unmountRequest := k8sresources.FlexVolumeUnmountRequest{MountPath: "some-mountpoint"} - unmountResponse := controller.Unmount(unmountRequest) - - Expect(unmountResponse.Status).To(Equal("Failure")) - Expect(unmountResponse.Message).To(MatchRegexp(errMsg.Error())) - Expect(unmountResponse.Device).To(Equal("")) - }) - It("should fail to umount if detach failed", func() { - errMsg := fmt.Errorf("error") - realMountPoint := fmt.Sprintf(resources.PathToMountUbiquityBlockDevices, "fakeWWN") - fakeExec.EvalSymlinksReturns(realMountPoint, nil) - fakeClient.DetachReturns(errMsg) - - unmountRequest := k8sresources.FlexVolumeUnmountRequest{MountPath: "/k8s/podid/some/pvname"} - unmountResponse := controller.Unmount(unmountRequest) - Expect(unmountResponse.Status).To(Equal("Failure")) - Expect(unmountResponse.Message).To(MatchRegexp(errMsg.Error())) - Expect(unmountResponse.Device).To(Equal("")) - detachRequest := fakeClient.DetachArgsForCall(0) - Expect(detachRequest.Name).To(Equal("pvname")) - }) - It("should fail to umount if detach failed", func() { - errMsg := fmt.Errorf("error") - realMountPoint := fmt.Sprintf(resources.PathToMountUbiquityBlockDevices, "fakeWWN") - fakeExec.EvalSymlinksReturns(realMountPoint, nil) - fakeClient.DetachReturns(errMsg) - - unmountRequest := k8sresources.FlexVolumeUnmountRequest{MountPath: "/k8s/podid/some/pvname"} - unmountResponse := controller.Unmount(unmountRequest) - Expect(unmountResponse.Status).To(Equal("Failure")) - Expect(unmountResponse.Message).To(MatchRegexp(errMsg.Error())) - Expect(unmountResponse.Device).To(Equal("")) - detachRequest := fakeClient.DetachArgsForCall(0) - Expect(detachRequest.Name).To(Equal("pvname")) - }) - - It("should fail to umount if fail to remove the slink", func() { - errMsg := fmt.Errorf("error") - realMountPoint := fmt.Sprintf(resources.PathToMountUbiquityBlockDevices, "fakeWWN") - fakeExec.EvalSymlinksReturns(realMountPoint, nil) - fakeClient.DetachReturns(nil) - fakeExec.RemoveReturns(errMsg) - - unmountRequest := k8sresources.FlexVolumeUnmountRequest{MountPath: "/k8s/podid/some/pvname"} - unmountResponse := controller.Unmount(unmountRequest) - Expect(unmountResponse.Status).To(Equal("Failure")) - Expect(unmountResponse.Message).To(MatchRegexp(errMsg.Error())) - Expect(unmountResponse.Device).To(Equal("")) - detachRequest := fakeClient.DetachArgsForCall(0) - Expect(detachRequest.Name).To(Equal("pvname")) - Expect(fakeExec.RemoveCallCount()).To(Equal(1)) - }) - It("should succeed to umount if the scbe umount flow finished ok", func() { - realMountPoint := fmt.Sprintf(resources.PathToMountUbiquityBlockDevices, "fakeWWN") - fakeExec.EvalSymlinksReturns(realMountPoint, nil) - fakeClient.DetachReturns(nil) - fakeExec.RemoveReturns(nil) - - unmountRequest := k8sresources.FlexVolumeUnmountRequest{MountPath: "/k8s/podid/some/pvname"} - unmountResponse := controller.Unmount(unmountRequest) - Expect(unmountResponse.Status).To(Equal("Success")) - Expect(unmountResponse.Message).To(Equal("Volume unmounted successfully")) - Expect(unmountResponse.Device).To(Equal("")) - detachRequest := fakeClient.DetachArgsForCall(0) - Expect(detachRequest.Name).To(Equal("pvname")) - Expect(fakeExec.RemoveCallCount()).To(Equal(1)) - }) - }) */ }) diff --git a/controller/errors.go b/controller/errors.go index f9fa7fb24..88e3f0d65 100644 --- a/controller/errors.go +++ b/controller/errors.go @@ -32,41 +32,44 @@ func (e *NoMounterForVolumeError) Error() string { const MissingWwnMountRequestErrorStr = "volume related to scbe backend must have mountRequest.Opts[Wwn] not found (expect to have wwn for scbe backend volume type)" const FailRemovePVorigDirErrorStr = "Failed removing existing volume directory" + type FailRemovePVorigDirError struct { err string dir error } func (e *FailRemovePVorigDirError) Error() string { - return fmt.Sprintf(FailRemovePVorigDirErrorStr + ". dir=[%s], err=[%#v]", e.dir, e.err) + return fmt.Sprintf(FailRemovePVorigDirErrorStr+". dir=[%s], err=[%#v]", e.dir, e.err) } const WrongSlinkErrorStr = "Idempotent - The existing slink point to a wrong mountpoint." + type wrongSlinkError struct { - slink string - wrongPointTo string + slink string + wrongPointTo string expectedPointTo string } func (e *wrongSlinkError) Error() string { - return fmt.Sprintf(WrongSlinkErrorStr + " slink=[%s] expected-mountpoint=[%s], wrong-mountpoint=[%s]", e.slink, e.expectedPointTo, e.wrongPointTo) + return fmt.Sprintf(WrongSlinkErrorStr+" slink=[%s] expected-mountpoint=[%s], wrong-mountpoint=[%s]", e.slink, e.expectedPointTo, e.wrongPointTo) } const SupportK8sVesion = "Support only k8s version >= 1.6." + type k8sVersionNotSupported struct { version string } func (e *k8sVersionNotSupported) Error() string { - return fmt.Sprintf(SupportK8sVesion + " Version [%s] is not supported.", e.version) + return fmt.Sprintf(SupportK8sVesion+" Version [%s] is not supported.", e.version) } const K8sPVDirectoryIsNotDirNorSlinkErrorStr = "k8s PV directory, k8s-mountpoint, is not a directory nor slink." + type k8sPVDirectoryIsNotDirNorSlinkError struct { slink string } func (e *k8sPVDirectoryIsNotDirNorSlinkError) Error() string { - return fmt.Sprintf(K8sPVDirectoryIsNotDirNorSlinkErrorStr + " slink=[%s]", e.slink) + return fmt.Sprintf(K8sPVDirectoryIsNotDirNorSlinkErrorStr+" slink=[%s]", e.slink) } - diff --git a/resources/resources.go b/resources/resources.go index 9dd395811..33da6a74a 100644 --- a/resources/resources.go +++ b/resources/resources.go @@ -3,6 +3,7 @@ package resources const KubernetesVersion_1_5 = "1.5" const KubernetesVersion_1_6OrLater = "atLeast1.6" const ProvisionerName = "ubiquity/flex" + // This ubiquity flexvolume name must be part of the flexvol CLI directory and CLI name in the minions. // Here is template of the path: // /usr/libexec/kubernetes/kubelet-plugins/volume/exec/${UbiquityK8sFlexVolumeDriverVendor}~${UbiquityK8sFlexVolumeDriverName}/${UbiquityK8sFlexVolumeDriverName} From 0df1bfeaeacd57228d1940fe0a8e69169075e1b3 Mon Sep 17 00:00:00 2001 From: Shay Berman Date: Mon, 21 May 2018 18:23:13 +0300 Subject: [PATCH 05/40] #177 : Improve error message for mount idempotent step. Print also the fileInfo in the error in case the mountpath is not dir nor slink. (feedback from Ran Harel code review PR #177). --- controller/controller.go | 2 +- controller/errors.go | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/controller/controller.go b/controller/controller.go index a4f7c96db..0487cf377 100644 --- a/controller/controller.go +++ b/controller/controller.go @@ -551,7 +551,7 @@ func (c *Controller) doAfterMount(mountRequest k8sresources.FlexVolumeMountReque "failed") } } else { - return c.logger.ErrorRet(&k8sPVDirectoryIsNotDirNorSlinkError{k8sPVDirectoryPath}, "failed") + return c.logger.ErrorRet(&k8sPVDirectoryIsNotDirNorSlinkError{k8sPVDirectoryPath, fileInfo}, "failed") } c.logger.Debug("Volume mounted successfully", logs.Args{{"mountedPath", mountedPath}}) diff --git a/controller/errors.go b/controller/errors.go index 88e3f0d65..5dc706f7e 100644 --- a/controller/errors.go +++ b/controller/errors.go @@ -18,6 +18,7 @@ package controller import ( "fmt" + "os" ) // TODO need to remove this error, since its moved to ubiquity it self @@ -67,9 +68,12 @@ func (e *k8sVersionNotSupported) Error() string { const K8sPVDirectoryIsNotDirNorSlinkErrorStr = "k8s PV directory, k8s-mountpoint, is not a directory nor slink." type k8sPVDirectoryIsNotDirNorSlinkError struct { - slink string + slink string + fileInfo os.FileInfo } func (e *k8sPVDirectoryIsNotDirNorSlinkError) Error() string { - return fmt.Sprintf(K8sPVDirectoryIsNotDirNorSlinkErrorStr+" slink=[%s]", e.slink) + // The error string contains also the fileInfo for debug purpose, in order to identify for example what is the actual FileInfo.Mode(). + return fmt.Sprintf(K8sPVDirectoryIsNotDirNorSlinkErrorStr+" slink=[%s], fileInfo=[%#v]", + e.slink, e.fileInfo) } From 4e4a3198e14aac84834f11e4531f6a3a252d3c10 Mon Sep 17 00:00:00 2001 From: Fei Huang <32086538+hfeish@users.noreply.github.com> Date: Thu, 24 May 2018 04:27:29 +0300 Subject: [PATCH 06/40] Fix/ub 624 flex should not write log into flex driver director (#166) * UB-624_Flex_should_not_write_log_into_flex_driver_director Signed-off-by: feihuang * Signed-off-by: feihuang * change log path to /tmp/log/ubiquity Signed-off-by: feihuang * remove ubiquity logrotate Signed-off-by: feihuang * Signed-off-by: feihuang * change log dir and do logrotate internal Signed-off-by: feihuang * Signed-off-by: feihuang * Signed-off-by: feihuang * Signed-off-by: feihuang * Signed-off-by: feihuang * To test, we need to use ubiquity branch fix/UB-624_Flex_should_not_write_log_into_flex_driver_directory will change back after test Signed-off-by: feihuang * remove version after build a testing build Signed-off-by: feihuang * Signed-off-by: feihuang * Signed-off-by: feihuang * Signed-off-by: feihuang * Signed-off-by: feihuang * Signed-off-by: feihuang * Signed-off-by: feihuang * add UT for load config Signed-off-by: feihuang * Signed-off-by: feihuang * add ginkgo ut Signed-off-by: feihuang --- Dockerfile.Flex | 2 - cmd/flex/main/cli.go | 18 +-- deploy/k8s_deployments/setup_flex.sh | 22 ++-- deploy/k8s_deployments/ubiquity_logrotate | 8 -- .../ubiquity-configmap.yml | 6 + .../ubiquity_installer.conf | 3 + .../ubiquity_installer.sh | 1 + .../yamls/ubiquity-k8s-flex-daemonset.yml | 19 +++ utils/utils.go | 9 ++ utils/utils_suite_test.go | 13 ++ utils/utils_test.go | 115 ++++++++++++++++++ 11 files changed, 186 insertions(+), 30 deletions(-) delete mode 100644 deploy/k8s_deployments/ubiquity_logrotate create mode 100644 utils/utils_suite_test.go create mode 100644 utils/utils_test.go diff --git a/Dockerfile.Flex b/Dockerfile.Flex index efa6be3be..46af584f3 100644 --- a/Dockerfile.Flex +++ b/Dockerfile.Flex @@ -8,10 +8,8 @@ RUN CGO_ENABLED=1 GOOS=linux go build -tags netgo -v -a --ldflags '-w -linkmode FROM alpine:3.7 RUN apk --no-cache add ca-certificates=20171114-r0 -RUN apk --update add logrotate ENV UBIQUITY_PLUGIN_VERIFY_CA=/var/lib/ubiquity/ssl/public/ubiquity-trusted-ca.crt WORKDIR /root/ -COPY --from=0 /go/src/github.com/IBM/ubiquity-k8s/deploy/k8s_deployments/ubiquity_logrotate /etc/logrotate.d/ COPY --from=0 /go/src/github.com/IBM/ubiquity-k8s/ubiquity-k8s-flex . COPY --from=0 /go/src/github.com/IBM/ubiquity-k8s/deploy/k8s_deployments/setup_flex.sh . COPY --from=0 /go/src/github.com/IBM/ubiquity-k8s/LICENSE . diff --git a/cmd/flex/main/cli.go b/cmd/flex/main/cli.go index 4f525db75..973a012d7 100644 --- a/cmd/flex/main/cli.go +++ b/cmd/flex/main/cli.go @@ -119,7 +119,7 @@ func (a *AttachCommand) Execute(args []string) error { } return printResponse(response) } - defer logs.InitFileLogger(logs.GetLogLevelFromString(config.LogLevel), path.Join(config.LogPath, k8sresources.UbiquityFlexLogFileName))() + defer logs.InitFileLogger(logs.GetLogLevelFromString(config.LogLevel), path.Join(config.LogPath, k8sresources.UbiquityFlexLogFileName), config.LogRotateMaxSize)() controller, err := createController(config) if err != nil { @@ -164,7 +164,7 @@ func (wfa *WaitForAttachCommand) Execute(args []string) error { } return printResponse(response) } - defer logs.InitFileLogger(logs.GetLogLevelFromString(config.LogLevel), path.Join(config.LogPath, k8sresources.UbiquityFlexLogFileName))() + defer logs.InitFileLogger(logs.GetLogLevelFromString(config.LogLevel), path.Join(config.LogPath, k8sresources.UbiquityFlexLogFileName), config.LogRotateMaxSize)() controller, err := createController(config) opts := make(map[string]string) err = json.Unmarshal([]byte(args[1]), &opts) @@ -203,7 +203,7 @@ func (d *IsAttachedCommand) Execute(args []string) error { } return printResponse(response) } - defer logs.InitFileLogger(logs.GetLogLevelFromString(config.LogLevel), path.Join(config.LogPath, k8sresources.UbiquityFlexLogFileName))() + defer logs.InitFileLogger(logs.GetLogLevelFromString(config.LogLevel), path.Join(config.LogPath, k8sresources.UbiquityFlexLogFileName), config.LogRotateMaxSize)() controller, err := createController(config) opts := make(map[string]string) err = json.Unmarshal([]byte(args[0]), &opts) @@ -253,7 +253,7 @@ func (d *DetachCommand) Execute(args []string) error { } return printResponse(response) } - defer logs.InitFileLogger(logs.GetLogLevelFromString(config.LogLevel), path.Join(config.LogPath, k8sresources.UbiquityFlexLogFileName))() + defer logs.InitFileLogger(logs.GetLogLevelFromString(config.LogLevel), path.Join(config.LogPath, k8sresources.UbiquityFlexLogFileName), config.LogRotateMaxSize)() controller, err := createController(config) if err != nil { @@ -288,7 +288,7 @@ func (d *MountDeviceCommand) Execute(args []string) error { } return printResponse(response) } - defer logs.InitFileLogger(logs.GetLogLevelFromString(config.LogLevel), path.Join(config.LogPath, k8sresources.UbiquityFlexLogFileName))() + defer logs.InitFileLogger(logs.GetLogLevelFromString(config.LogLevel), path.Join(config.LogPath, k8sresources.UbiquityFlexLogFileName), config.LogRotateMaxSize)() controller, err := createController(config) opts := make(map[string]string) err = json.Unmarshal([]byte(args[2]), &opts) @@ -327,7 +327,7 @@ func (d *UnmountDeviceCommand) Execute(args []string) error { } return printResponse(response) } - defer logs.InitFileLogger(logs.GetLogLevelFromString(config.LogLevel), path.Join(config.LogPath, k8sresources.UbiquityFlexLogFileName))() + defer logs.InitFileLogger(logs.GetLogLevelFromString(config.LogLevel), path.Join(config.LogPath, k8sresources.UbiquityFlexLogFileName), config.LogRotateMaxSize)() controller, err := createController(config) unmountDeviceRequest := k8sresources.FlexVolumeUnmountDeviceRequest{Name: args[0]} @@ -408,7 +408,7 @@ func (m *MountCommand) Execute(args []string) error { return printResponse(response) } - defer logs.InitFileLogger(logs.GetLogLevelFromString(config.LogLevel), path.Join(config.LogPath, k8sresources.UbiquityFlexLogFileName))() + defer logs.InitFileLogger(logs.GetLogLevelFromString(config.LogLevel), path.Join(config.LogPath, k8sresources.UbiquityFlexLogFileName), config.LogRotateMaxSize)() controller, err := createController(config) if err != nil { @@ -443,7 +443,7 @@ func (u *UnmountCommand) Execute(args []string) error { } return printResponse(response) } - defer logs.InitFileLogger(logs.GetLogLevelFromString(config.LogLevel), path.Join(config.LogPath, k8sresources.UbiquityFlexLogFileName))() + defer logs.InitFileLogger(logs.GetLogLevelFromString(config.LogLevel), path.Join(config.LogPath, k8sresources.UbiquityFlexLogFileName), config.LogRotateMaxSize)() controller, err := createController(config) if err != nil { @@ -470,7 +470,7 @@ func (i *TestUbiquityCommand) Execute(args []string) error { } return printResponse(response) } - defer logs.InitFileLogger(logs.GetLogLevelFromString(config.LogLevel), path.Join(config.LogPath, k8sresources.UbiquityFlexLogFileName))() + defer logs.InitFileLogger(logs.GetLogLevelFromString(config.LogLevel), path.Join(config.LogPath, k8sresources.UbiquityFlexLogFileName), config.LogRotateMaxSize)() controller, err := createController(config) if err != nil { response := k8sresources.FlexVolumeResponse{ diff --git a/deploy/k8s_deployments/setup_flex.sh b/deploy/k8s_deployments/setup_flex.sh index 20362316d..7e2136202 100755 --- a/deploy/k8s_deployments/setup_flex.sh +++ b/deploy/k8s_deployments/setup_flex.sh @@ -6,9 +6,7 @@ # 1. Deploy flex driver & config file & trusted ca file(if exist) from the container into the host path # /usr/libexec/kubernetes/kubelet-plugins/volume/exec/ibm~ubiquity-k8s-flex # 2. Run tail -f on the flex log file, so it will be visible via kubectl logs -# 3. Start infinite loop with logrotate every 24 hours on the host flex log file -# /usr/libexec/kubernetes/kubelet-plugins/volume/exec/ibm~ubiquity-k8s-flex/ubiquity-k8s-flex.log -# The rotation policy is based on /etc/logrotate.d/ubiquity_logrotate +# 3. Start infinite loop every 24 hours on the host for tailing the flex log file ########################################################################### set -o errexit @@ -43,6 +41,8 @@ function generate_flex_conf_from_envs_and_install_it() [ -z "$UBIQUITY_IP_ADDRESS" ] && missing_env UBIQUITY_IP_ADDRESS || : # Other environment variable with default values + [ -z "$FLEX_LOG_DIR" ] && FLEX_LOG_DIR=/var/log || : + [ -z "$FLEX_LOG_ROTATE_MAXSIZE" ] && FLEX_LOG_ROTATE_MAXSIZE=50 || : [ -z "$LOG_LEVEL" ] && LOG_LEVEL=info || : [ -z "$SKIP_RESCAN_ISCSI" ] && SKIP_RESCAN_ISCSI=false || : [ -z "$UBIQUITY_PLUGIN_USE_SSL" ] && UBIQUITY_PLUGIN_USE_SSL=true || : @@ -53,7 +53,8 @@ function generate_flex_conf_from_envs_and_install_it() cat > $FLEX_TMP << EOF # This file was generated automatically by the $DRIVER Pod. -logPath = "${HOST_K8S_PLUGIN_DIR}/${DRIVER_DIR}" +logPath = "$FLEX_LOG_DIR" +logRotateMaxSize = $FLEX_LOG_ROTATE_MAXSIZE backends = ["$UBIQUITY_BACKEND"] logLevel = "$LOG_LEVEL" @@ -82,7 +83,7 @@ function test_flex_driver() { echo "Test the flex driver by running $> ${MNT_FLEX_DRIVER_DIR}/$DRIVER testubiquity" testubiquity=`${MNT_FLEX_DRIVER_DIR}/$DRIVER testubiquity 2>&1` - flex_log=${MNT_FLEX_DRIVER_DIR}/ubiquity-k8s-flex.log + flex_log=${FLEX_LOG_DIR}/ubiquity-k8s-flex.log if echo "$testubiquity" | grep '"status":"Success"' >/dev/null; then echo "$testubiquity" echo "Flex test passed Ok" @@ -143,14 +144,13 @@ echo "" test_flex_driver echo "" -echo "This Pod will handle log rotation for the on the host [${HOST_K8S_PLUGIN_DIR}/${DRIVER_DIR}/${DRIVER}.log]" +echo "This Pod will handle log rotation for the on the host [${FLEX_LOG_DIR}/${DRIVER}.log]" echo "Running in the background tail -F , so the log will be visible though kubectl logs " echo "[`date`] Start to run in background #>" -echo "tail -F ${HOST_K8S_PLUGIN_DIR}/${DRIVER_DIR}/${DRIVER}.log" +echo "tail -F ${FLEX_LOG_DIR}/${DRIVER}.log" echo "-----------------------------------------------" -tail -F ${MNT_FLEX_DRIVER_DIR}/ubiquity-k8s-flex.log & +tail -F ${FLEX_LOG_DIR}/${DRIVER}.log & while : ; do - sleep 86400 # every 24 hours - /usr/sbin/logrotate /etc/logrotate.d/ubiquity_logrotate -done + sleep 86400 # every 24 hours +done \ No newline at end of file diff --git a/deploy/k8s_deployments/ubiquity_logrotate b/deploy/k8s_deployments/ubiquity_logrotate deleted file mode 100644 index 55048fa3c..000000000 --- a/deploy/k8s_deployments/ubiquity_logrotate +++ /dev/null @@ -1,8 +0,0 @@ -/usr/libexec/kubernetes/kubelet-plugins/volume/exec/ibm~ubiquity-k8s-flex/ubiquity-k8s-flex.log { - su root root - size 50M - rotate 5 - compress - copytruncate - create 0600 root root -} diff --git a/scripts/installer-for-ibm-storage-enabler-for-containers/ubiquity-configmap.yml b/scripts/installer-for-ibm-storage-enabler-for-containers/ubiquity-configmap.yml index ceeded588..f1761d6e1 100644 --- a/scripts/installer-for-ibm-storage-enabler-for-containers/ubiquity-configmap.yml +++ b/scripts/installer-for-ibm-storage-enabler-for-containers/ubiquity-configmap.yml @@ -32,6 +32,12 @@ data: # The following keys are used by ubiquity, ubiquity-k8s-provisioner deployments, And ubiquity-k8s-flex daemon-set # ---------------------------------------------------------------------------------------------------------------------------- + # Flex log path. Allow to configure it, just make sure the the new path exist on all the minons and update the hostpath in the Flex daemonset + FLEX-LOG-DIR: "FLEX_LOG_DIR_VALUE" + + # Maxlog size(MB) for rotate + FLEX-LOG-ROTATE-MAXSIZE: "50" + # Log level. Allowed values: debug, info, error. LOG-LEVEL: "LOG_LEVEL_VALUE" diff --git a/scripts/installer-for-ibm-storage-enabler-for-containers/ubiquity_installer.conf b/scripts/installer-for-ibm-storage-enabler-for-containers/ubiquity_installer.conf index 1ded39406..be4b27a1c 100644 --- a/scripts/installer-for-ibm-storage-enabler-for-containers/ubiquity_installer.conf +++ b/scripts/installer-for-ibm-storage-enabler-for-containers/ubiquity_installer.conf @@ -48,6 +48,9 @@ SKIP_RESCAN_ISCSI_VALUE=false # Parameters in ubiquity-configmap.yml that impact on "ubiquity" and "ubiquity-k8s-provisioner" deployments, And "ubiquity-k8s-flex" daemonset #----------------------------------------------------------------- +# Flex log directory. If you change the default, then make the new path exist on all the nodes and update the Flex daemonset hostpath according. +FLEX_LOG_DIR_VALUE=/var/log + # Log level. Allowed values: debug, info, error. LOG_LEVEL_VALUE=info diff --git a/scripts/installer-for-ibm-storage-enabler-for-containers/ubiquity_installer.sh b/scripts/installer-for-ibm-storage-enabler-for-containers/ubiquity_installer.sh index c43346feb..79e47ee66 100755 --- a/scripts/installer-for-ibm-storage-enabler-for-containers/ubiquity_installer.sh +++ b/scripts/installer-for-ibm-storage-enabler-for-containers/ubiquity_installer.sh @@ -200,6 +200,7 @@ function update-ymls() KEY_FILE_DICT['UBIQUITY_INSTANCE_NAME_VALUE']="${UBIQUITY_CONFIGMAP_YML}" KEY_FILE_DICT['IBM_UBIQUITY_DB_PV_NAME_VALUE']="${UBIQUITY_CONFIGMAP_YML} ${PVCS_USES_STORAGECLASS_YML}" KEY_FILE_DICT['DEFAULT_FSTYPE_VALUE']="${UBIQUITY_CONFIGMAP_YML}" + KEY_FILE_DICT['FLEX_LOG_DIR_VALUE']="${UBIQUITY_CONFIGMAP_YML} ${UBIQUITY_FLEX_DAEMONSET_YML}" KEY_FILE_DICT['LOG_LEVEL_VALUE']="${UBIQUITY_CONFIGMAP_YML}" KEY_FILE_DICT['SSL_MODE_VALUE']="${UBIQUITY_CONFIGMAP_YML}" KEY_FILE_DICT['SKIP_RESCAN_ISCSI_VALUE']="${UBIQUITY_CONFIGMAP_YML}" diff --git a/scripts/installer-for-ibm-storage-enabler-for-containers/yamls/ubiquity-k8s-flex-daemonset.yml b/scripts/installer-for-ibm-storage-enabler-for-containers/yamls/ubiquity-k8s-flex-daemonset.yml index 1d36232d0..2e0dd02af 100644 --- a/scripts/installer-for-ibm-storage-enabler-for-containers/yamls/ubiquity-k8s-flex-daemonset.yml +++ b/scripts/installer-for-ibm-storage-enabler-for-containers/yamls/ubiquity-k8s-flex-daemonset.yml @@ -32,6 +32,18 @@ spec: - name: UBIQUITY_BACKEND # "IBM Storage Enabler for Containers" supports "scbe" (IBM Spectrum Connect) as its backend. value: "scbe" + - name: FLEX_LOG_DIR # /var/log default + valueFrom: + configMapKeyRef: + name: ubiquity-configmap + key: FLEX-LOG-DIR + + - name: FLEX_LOG_ROTATE_MAXSIZE # 50MB default + valueFrom: + configMapKeyRef: + name: ubiquity-configmap + key: FLEX-LOG-ROTATE-MAXSIZE + - name: LOG_LEVEL # debug / info / error valueFrom: configMapKeyRef: @@ -74,6 +86,9 @@ spec: volumeMounts: - name: host-k8splugindir mountPath: /usr/libexec/kubernetes/kubelet-plugins/volume/exec + + - name: flex-log-dir + mountPath: FLEX_LOG_DIR_VALUE # Certificate Set : use the below volumeMounts only if predefine certificate given # Cert # - name: ubiquity-public-certificates # Cert # mountPath: /var/lib/ubiquity/ssl/public @@ -83,6 +98,10 @@ spec: - name: host-k8splugindir hostPath: path: /usr/libexec/kubernetes/kubelet-plugins/volume/exec # This directory must exist on the host + + - name: flex-log-dir + hostPath: + path: FLEX_LOG_DIR_VALUE # This directory must exist on the host # Certificate Set : use the below volumes only if predefine certificate given # Cert # - name: ubiquity-public-certificates # Cert # configMap: diff --git a/utils/utils.go b/utils/utils.go index ffd87d5c8..f9dce298a 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -11,6 +11,15 @@ func LoadConfig() (resources.UbiquityPluginConfig, error) { config := resources.UbiquityPluginConfig{} config.LogLevel = os.Getenv("LOG_LEVEL") + LogRotateMaxSize, err := strconv.Atoi(os.Getenv("FLEX_LOG_ROTATE_MAXSIZE")) + if err != nil { + if LogRotateMaxSize == 0 { + LogRotateMaxSize = 50 + } else { + return config, err + } + } + config.LogRotateMaxSize = LogRotateMaxSize config.LogPath = os.Getenv("LOG_PATH") config.Backends = strings.Split(os.Getenv("BACKENDS"), ",") ubiquity := resources.UbiquityServerConnectionInfo{} diff --git a/utils/utils_suite_test.go b/utils/utils_suite_test.go new file mode 100644 index 000000000..f160db602 --- /dev/null +++ b/utils/utils_suite_test.go @@ -0,0 +1,13 @@ +package utils_test + +import ( + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + + "testing" +) + +func TestUtils(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "Utils Suite") +} diff --git a/utils/utils_test.go b/utils/utils_test.go new file mode 100644 index 000000000..493ab12d2 --- /dev/null +++ b/utils/utils_test.go @@ -0,0 +1,115 @@ +package utils_test + +import ( + . "github.com/IBM/ubiquity-k8s/utils" + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + "os" + "strconv" +) + +var _ = Describe("Utils", func() { + var ( + tests1 = []struct { + envVar string + in string + out string + }{ + {"LOG_LEVEL", "debug", "debug"}, + {"FLEX_LOG_ROTATE_MAXSIZE", "100", "100"}, + {"LOG_PATH", "/var/log", "/var/log"}, + {"BACKENDS", "SCBE", "SCBE"}, + {"UBIQUITY_PORT", "9999", "9999"}, + {"UBIQUITY_ADDRESS", "9.9.9.9", "9.9.9.9"}, + {"SCBE_SKIP_RESCAN_ISCSI", "true", "true"}, + {"UBIQUITY_USERNAME", "ubiquity", "ubiquity"}, + {"UBIQUITY_PASSWORD", "ubiquity", "ubiquity"}, + } + + tests2 = []struct { + envVar string + in string + out string + }{ + {"LOG_LEVEL", "debug", "debug"}, + {"FLEX_LOG_ROTATE_MAXSIZE", "", "50"}, + {"LOG_PATH", "/var/log", "/var/log"}, + {"BACKENDS", "SCBE", "SCBE"}, + {"UBIQUITY_PORT", "9999", "9999"}, + {"UBIQUITY_ADDRESS", "9.9.9.9", "9.9.9.9"}, + {"SCBE_SKIP_RESCAN_ISCSI", "", "false"}, + {"UBIQUITY_USERNAME", "ubiquity", "ubiquity"}, + {"UBIQUITY_PASSWORD", "ubiquity", "ubiquity"}, + } + ) + + Context("set the correct env val", func() { + BeforeEach(func() { + for _, data := range tests1 { + os.Setenv(data.envVar, data.in) + } + }) + It("verify the vals which get from LoadConfig are expected", func() { + ubiquityConfig, err := LoadConfig() + Expect(err).To(Not(HaveOccurred())) + loadData := []struct { + envVar string + val string + }{ + + {"LOG_LEVEL", ubiquityConfig.LogLevel}, + {"FLEX_LOG_ROTATE_MAXSIZE", strconv.Itoa(ubiquityConfig.LogRotateMaxSize)}, + {"LOG_PATH", ubiquityConfig.LogPath}, + {"BACKENDS", ubiquityConfig.Backends[0]}, + {"UBIQUITY_PORT", strconv.Itoa(ubiquityConfig.UbiquityServer.Port)}, + {"UBIQUITY_ADDRESS", ubiquityConfig.UbiquityServer.Address}, + {"SCBE_SKIP_RESCAN_ISCSI", strconv.FormatBool(ubiquityConfig.ScbeRemoteConfig.SkipRescanISCSI)}, + {"UBIQUITY_USERNAME", ubiquityConfig.CredentialInfo.UserName}, + {"UBIQUITY_PASSWORD", ubiquityConfig.CredentialInfo.Password}, + } + for _, data := range tests1 { + for _, loaddata := range loadData { + if loaddata.envVar == data.envVar { + Expect(loaddata.val).To(Equal(data.out)) + } + } + } + }) + + }) + + Context("Without set FLEX_LOG_ROTATE_MAXSIZE and SCBE_SKIP_RESCAN_ISCSI", func() { + BeforeEach(func() { + for _, data := range tests2 { + os.Setenv(data.envVar, data.in) + } + }) + It("verify the vals which get from LoadConfig are expected", func() { + ubiquityConfig, err := LoadConfig() + Expect(err).To(Not(HaveOccurred())) + loadData := []struct { + envVar string + val string + }{ + + {"LOG_LEVEL", ubiquityConfig.LogLevel}, + {"FLEX_LOG_ROTATE_MAXSIZE", strconv.Itoa(ubiquityConfig.LogRotateMaxSize)}, + {"LOG_PATH", ubiquityConfig.LogPath}, + {"BACKENDS", ubiquityConfig.Backends[0]}, + {"UBIQUITY_PORT", strconv.Itoa(ubiquityConfig.UbiquityServer.Port)}, + {"UBIQUITY_ADDRESS", ubiquityConfig.UbiquityServer.Address}, + {"SCBE_SKIP_RESCAN_ISCSI", strconv.FormatBool(ubiquityConfig.ScbeRemoteConfig.SkipRescanISCSI)}, + {"UBIQUITY_USERNAME", ubiquityConfig.CredentialInfo.UserName}, + {"UBIQUITY_PASSWORD", ubiquityConfig.CredentialInfo.Password}, + } + for _, data := range tests2 { + for _, loaddata := range loadData { + if loaddata.envVar == data.envVar { + Expect(loaddata.val).To(Equal(data.out)) + } + } + } + }) + + }) +}) From 0a523a7815a1cde6f833d936ac446d9700f324c7 Mon Sep 17 00:00:00 2001 From: olgashtivelman <33713489+olgashtivelman@users.noreply.github.com> Date: Wed, 13 Jun 2018 10:00:56 +0300 Subject: [PATCH 07/40] UB-1099: add go_id:request_id to flex and provisioner logs (#191) Added request id + go routine id to provisioner and flex logs. --- cmd/flex/main/cli.go | 32 ++++-- controller/controller.go | 178 +++++++++++++++++++-------------- glide.yaml | 2 +- resources/resources.go | 28 ++++-- utils/utils.go | 3 +- volume/provision.go | 47 +++++---- volume/provision_suite_test.go | 2 + 7 files changed, 178 insertions(+), 114 deletions(-) diff --git a/cmd/flex/main/cli.go b/cmd/flex/main/cli.go index 973a012d7..ad843c6d4 100644 --- a/cmd/flex/main/cli.go +++ b/cmd/flex/main/cli.go @@ -27,12 +27,13 @@ import ( "github.com/IBM/ubiquity-k8s/controller" flags "github.com/jessevdk/go-flags" + "strconv" + k8sresources "github.com/IBM/ubiquity-k8s/resources" "github.com/IBM/ubiquity/remote" "github.com/IBM/ubiquity/resources" "github.com/IBM/ubiquity/utils" "github.com/IBM/ubiquity/utils/logs" - "strconv" ) var configFile = flag.String( @@ -88,6 +89,9 @@ type AttachCommand struct { func (a *AttachCommand) Execute(args []string) error { var version string var hostname string + + requestContext := logs.GetNewRequestContext() + if len(args) < 1 { response := k8sresources.FlexVolumeResponse{ @@ -135,7 +139,7 @@ func (a *AttachCommand) Execute(args []string) error { return printResponse(response) } - attachRequest := k8sresources.FlexVolumeAttachRequest{Name: volumeName, Host: hostname, Opts: attachRequestOpts, Version: version} + attachRequest := k8sresources.FlexVolumeAttachRequest{Name: volumeName, Host: hostname, Opts: attachRequestOpts, Version: version, Context: requestContext} attachResponse := controller.Attach(attachRequest) return printResponse(attachResponse) @@ -148,6 +152,8 @@ type WaitForAttachCommand struct { } func (wfa *WaitForAttachCommand) Execute(args []string) error { + requestContext := logs.GetNewRequestContext() + if len(args) < 2 { response := k8sresources.FlexVolumeResponse{ @@ -160,7 +166,7 @@ func (wfa *WaitForAttachCommand) Execute(args []string) error { if err != nil { response := k8sresources.FlexVolumeResponse{ Status: "Failure", - Message: fmt.Sprintf("Failed to read config in waitForAttach volume %#v", err), + Message: fmt.Sprintf("Failed to read config in waitForAttach volume %#v ", err), } return printResponse(response) } @@ -175,7 +181,7 @@ func (wfa *WaitForAttachCommand) Execute(args []string) error { } return printResponse(response) } - waitForAttachRequest := k8sresources.FlexVolumeWaitForAttachRequest{Name: args[0], Opts: opts} + waitForAttachRequest := k8sresources.FlexVolumeWaitForAttachRequest{Name: args[0], Opts: opts, Context: requestContext} response := controller.WaitForAttach(waitForAttachRequest) return printResponse(response) } @@ -187,6 +193,7 @@ type IsAttachedCommand struct { } func (d *IsAttachedCommand) Execute(args []string) error { + requestContext := logs.GetNewRequestContext() if len(args) < 2 { response := k8sresources.FlexVolumeResponse{ @@ -214,7 +221,7 @@ func (d *IsAttachedCommand) Execute(args []string) error { } return printResponse(response) } - isAttachedRequest := k8sresources.FlexVolumeIsAttachedRequest{Opts: opts, Host: args[1]} + isAttachedRequest := k8sresources.FlexVolumeIsAttachedRequest{Opts: opts, Host: args[1], Context: requestContext} response := controller.IsAttached(isAttachedRequest) return printResponse(response) } @@ -227,6 +234,7 @@ type DetachCommand struct { } func (d *DetachCommand) Execute(args []string) error { + requestContext := logs.GetNewRequestContext() var hostname string var version string if len(args) < 1 { @@ -260,7 +268,7 @@ func (d *DetachCommand) Execute(args []string) error { panic("backend not found") } - detachRequest := k8sresources.FlexVolumeDetachRequest{Name: mountDevice, Host: hostname, Version: version} + detachRequest := k8sresources.FlexVolumeDetachRequest{Name: mountDevice, Host: hostname, Version: version, Context: requestContext} detachResponse := controller.Detach(detachRequest) return printResponse(detachResponse) } @@ -272,6 +280,7 @@ type MountDeviceCommand struct { } func (d *MountDeviceCommand) Execute(args []string) error { + requestContext := logs.GetNewRequestContext() if len(args) < 3 { response := k8sresources.FlexVolumeResponse{ @@ -299,7 +308,7 @@ func (d *MountDeviceCommand) Execute(args []string) error { } return printResponse(response) } - mountDeviceRequest := k8sresources.FlexVolumeMountDeviceRequest{Path: args[0], Name: args[1], Opts: opts} + mountDeviceRequest := k8sresources.FlexVolumeMountDeviceRequest{Path: args[0], Name: args[1], Opts: opts, Context: requestContext} response := controller.MountDevice(mountDeviceRequest) return printResponse(response) } @@ -311,6 +320,7 @@ type UnmountDeviceCommand struct { } func (d *UnmountDeviceCommand) Execute(args []string) error { + requestContext := logs.GetNewRequestContext() if len(args) < 1 { response := k8sresources.FlexVolumeResponse{ @@ -330,7 +340,7 @@ func (d *UnmountDeviceCommand) Execute(args []string) error { defer logs.InitFileLogger(logs.GetLogLevelFromString(config.LogLevel), path.Join(config.LogPath, k8sresources.UbiquityFlexLogFileName), config.LogRotateMaxSize)() controller, err := createController(config) - unmountDeviceRequest := k8sresources.FlexVolumeUnmountDeviceRequest{Name: args[0]} + unmountDeviceRequest := k8sresources.FlexVolumeUnmountDeviceRequest{Name: args[0], Context: requestContext} response := controller.UnmountDevice(unmountDeviceRequest) return printResponse(response) } @@ -349,6 +359,8 @@ func (m *MountCommand) Execute(args []string) error { var ok bool var version string + requestContext := logs.GetNewRequestContext() + //should error out when not enough args if len(args) < 2 { @@ -397,6 +409,7 @@ func (m *MountCommand) Execute(args []string) error { MountDevice: volumeName, // The PV name Opts: mountOpts, Version: version, + Context: requestContext, } config, err := readConfig(*configFile) @@ -415,6 +428,7 @@ func (m *MountCommand) Execute(args []string) error { panic("backend not found") } mountResponse := controller.Mount(mountRequest) + return printResponse(mountResponse) } @@ -425,6 +439,7 @@ type UnmountCommand struct { } func (u *UnmountCommand) Execute(args []string) error { + requestContext := logs.GetNewRequestContext() if len(args) < 1 { response := k8sresources.FlexVolumeResponse{ @@ -452,6 +467,7 @@ func (u *UnmountCommand) Execute(args []string) error { unmountRequest := k8sresources.FlexVolumeUnmountRequest{ MountPath: mountDir, + Context: requestContext, } unmountResponse := controller.Unmount(unmountRequest) return printResponse(unmountResponse) diff --git a/controller/controller.go b/controller/controller.go index 0487cf377..3a07681ec 100644 --- a/controller/controller.go +++ b/controller/controller.go @@ -131,6 +131,9 @@ func (c *Controller) TestUbiquity(config resources.UbiquityPluginConfig) k8sreso //Attach method attaches a volume to a host func (c *Controller) Attach(attachRequest k8sresources.FlexVolumeAttachRequest) k8sresources.FlexVolumeResponse { + go_id := logs.GetGoID() + logs.GoIdToRequestIdMap.Store(go_id, attachRequest.Context) + defer logs.GetDeleteFromMapFunc(go_id) defer c.logger.Trace(logs.DEBUG)() var response k8sresources.FlexVolumeResponse c.logger.Debug("", logs.Args{{"request", attachRequest}}) @@ -168,6 +171,9 @@ func (c *Controller) GetVolumeName(getVolumeNameRequest k8sresources.FlexVolumeG //WaitForAttach Waits for a volume to get attached to the node func (c *Controller) WaitForAttach(waitForAttachRequest k8sresources.FlexVolumeWaitForAttachRequest) k8sresources.FlexVolumeResponse { + go_id := logs.GetGoID() + logs.GoIdToRequestIdMap.Store(go_id, waitForAttachRequest.Context) + defer logs.GetDeleteFromMapFunc(go_id) defer c.logger.Trace(logs.DEBUG)() var response k8sresources.FlexVolumeResponse c.logger.Debug("", logs.Args{{"request", waitForAttachRequest}}) @@ -182,6 +188,9 @@ func (c *Controller) WaitForAttach(waitForAttachRequest k8sresources.FlexVolumeW //IsAttached checks if volume is attached func (c *Controller) IsAttached(isAttachedRequest k8sresources.FlexVolumeIsAttachedRequest) k8sresources.FlexVolumeResponse { + go_id := logs.GetGoID() + logs.GoIdToRequestIdMap.Store(go_id, isAttachedRequest.Context) + defer logs.GetDeleteFromMapFunc(go_id) defer c.logger.Trace(logs.DEBUG)() var response k8sresources.FlexVolumeResponse c.logger.Debug("", logs.Args{{"request", isAttachedRequest}}) @@ -206,6 +215,9 @@ func (c *Controller) IsAttached(isAttachedRequest k8sresources.FlexVolumeIsAttac //Detach detaches the volume/ fileset from the pod func (c *Controller) Detach(detachRequest k8sresources.FlexVolumeDetachRequest) k8sresources.FlexVolumeResponse { + go_id := logs.GetGoID() + logs.GoIdToRequestIdMap.Store(go_id, detachRequest.Context) + defer logs.GetDeleteFromMapFunc(go_id) defer c.logger.Trace(logs.DEBUG)() var response k8sresources.FlexVolumeResponse c.logger.Debug("", logs.Args{{"request", detachRequest}}) @@ -237,6 +249,9 @@ func (c *Controller) Detach(detachRequest k8sresources.FlexVolumeDetachRequest) //MountDevice mounts a device in a given location func (c *Controller) MountDevice(mountDeviceRequest k8sresources.FlexVolumeMountDeviceRequest) k8sresources.FlexVolumeResponse { + go_id := logs.GetGoID() + logs.GoIdToRequestIdMap.Store(go_id, mountDeviceRequest.Context) + defer logs.GetDeleteFromMapFunc(go_id) defer c.logger.Trace(logs.DEBUG)() var response k8sresources.FlexVolumeResponse c.logger.Debug("", logs.Args{{"request", mountDeviceRequest}}) @@ -251,6 +266,9 @@ func (c *Controller) MountDevice(mountDeviceRequest k8sresources.FlexVolumeMount //UnmountDevice checks if volume is unmounted func (c *Controller) UnmountDevice(unmountDeviceRequest k8sresources.FlexVolumeUnmountDeviceRequest) k8sresources.FlexVolumeResponse { + go_id := logs.GetGoID() + logs.GoIdToRequestIdMap.Store(go_id, unmountDeviceRequest.Context) + defer logs.GetDeleteFromMapFunc(go_id) defer c.logger.Trace(logs.DEBUG)() var response k8sresources.FlexVolumeResponse c.logger.Debug("", logs.Args{{"request", unmountDeviceRequest}}) @@ -265,6 +283,9 @@ func (c *Controller) UnmountDevice(unmountDeviceRequest k8sresources.FlexVolumeU //Mount method allows to mount the volume/fileset to a given location for a pod func (c *Controller) Mount(mountRequest k8sresources.FlexVolumeMountRequest) k8sresources.FlexVolumeResponse { + go_id := logs.GetGoID() + logs.GoIdToRequestIdMap.Store(go_id, mountRequest.Context) + defer logs.GetDeleteFromMapFunc(go_id) defer c.logger.Trace(logs.DEBUG)() var response k8sresources.FlexVolumeResponse c.logger.Debug("", logs.Args{{"request", mountRequest}}) @@ -296,6 +317,9 @@ func (c *Controller) Mount(mountRequest k8sresources.FlexVolumeMountRequest) k8s //Unmount methods unmounts the volume from the pod func (c *Controller) Unmount(unmountRequest k8sresources.FlexVolumeUnmountRequest) k8sresources.FlexVolumeResponse { + go_id := logs.GetGoID() + logs.GoIdToRequestIdMap.Store(go_id, unmountRequest.Context) + defer logs.GetDeleteFromMapFunc(go_id) defer c.logger.Trace(logs.DEBUG)() // locking for concurrent rescans and reduce rescans if no need c.logger.Debug("Ask for unmountFlock for mountpath", logs.Args{{"mountpath", unmountRequest.MountPath}}) @@ -310,6 +334,7 @@ func (c *Controller) Unmount(unmountRequest k8sresources.FlexVolumeUnmountReques c.logger.Debug("Got unmountFlock for mountpath", logs.Args{{"mountpath", unmountRequest.MountPath}}) defer c.unmountFlock.Unlock() defer c.logger.Debug("Released unmountFlock for mountpath", logs.Args{{"mountpath", unmountRequest.MountPath}}) + var response k8sresources.FlexVolumeResponse c.logger.Debug("", logs.Args{{"request", unmountRequest}}) @@ -362,7 +387,7 @@ func (c *Controller) doLegacyDetach(unmountRequest k8sresources.FlexVolumeUnmoun var err error pvName := path.Base(unmountRequest.MountPath) - detachRequest := k8sresources.FlexVolumeDetachRequest{Name: pvName} + detachRequest := k8sresources.FlexVolumeDetachRequest{Name: pvName, Context: unmountRequest.Context} err = c.doDetach(detachRequest, false) if err != nil { return c.logger.ErrorRet(err, "failed") @@ -376,7 +401,7 @@ func (c *Controller) doLegacyDetach(unmountRequest k8sresources.FlexVolumeUnmoun return nil } -func (c *Controller) getMounterForBackend(backend string) (resources.Mounter, error) { +func (c *Controller) getMounterForBackend(backend string, requestContext resources.RequestContext) (resources.Mounter, error) { defer c.logger.Trace(logs.DEBUG)() var err error mounterInst, ok := c.mounterPerBackend[backend] @@ -385,7 +410,7 @@ func (c *Controller) getMounterForBackend(backend string) (resources.Mounter, er return mounterInst, nil } else { // mounter not exist in the controller backend list, so get it now - c.mounterPerBackend[backend], err = c.mounterFactory.GetMounterPerBackend(backend, c.legacyLogger, c.config) + c.mounterPerBackend[backend], err = c.mounterFactory.GetMounterPerBackend(backend, c.legacyLogger, c.config, requestContext) if err != nil { return nil, err } @@ -400,7 +425,7 @@ func (c *Controller) prepareUbiquityMountRequest(mountRequest k8sresources.FlexV defer c.logger.Trace(logs.DEBUG)() // Prepare request for mounter - step1 get volume's config from ubiquity - getVolumeConfigRequest := resources.GetVolumeConfigRequest{Name: mountRequest.MountDevice} + getVolumeConfigRequest := resources.GetVolumeConfigRequest{Name: mountRequest.MountDevice, Context: mountRequest.Context} volumeConfig, err := c.Client.GetVolumeConfig(getVolumeConfigRequest) if err != nil { return resources.MountRequest{}, c.logger.ErrorRet(err, "Client.GetVolumeConfig failed") @@ -414,19 +439,19 @@ func (c *Controller) prepareUbiquityMountRequest(mountRequest k8sresources.FlexV return resources.MountRequest{}, c.logger.ErrorRet(err, "failed") } volumeMountpoint := fmt.Sprintf(resources.PathToMountUbiquityBlockDevices, wwn) - ubMountRequest := resources.MountRequest{Mountpoint: volumeMountpoint, VolumeConfig: volumeConfig} + ubMountRequest := resources.MountRequest{Mountpoint: volumeMountpoint, VolumeConfig: volumeConfig, Context : mountRequest.Context} return ubMountRequest, nil } -func (c *Controller) getMounterByPV(pvname string) (resources.Mounter, error) { +func (c *Controller) getMounterByPV(mountRequest k8sresources.FlexVolumeMountRequest) (resources.Mounter, error) { defer c.logger.Trace(logs.DEBUG)() - getVolumeRequest := resources.GetVolumeRequest{Name: pvname} + getVolumeRequest := resources.GetVolumeRequest{Name: mountRequest.MountDevice, Context: mountRequest.Context} volume, err := c.Client.GetVolume(getVolumeRequest) if err != nil { return nil, c.logger.ErrorRet(err, "GetVolume failed") } - mounter, err := c.getMounterForBackend(volume.Backend) + mounter, err := c.getMounterForBackend(volume.Backend, mountRequest.Context) if err != nil { return nil, c.logger.ErrorRet(err, "getMounterForBackend failed") } @@ -442,7 +467,7 @@ func (c *Controller) doMount(mountRequest k8sresources.FlexVolumeMountRequest) ( return "", c.logger.ErrorRet(&k8sVersionNotSupported{mountRequest.Version}, "failed") } - mounter, err := c.getMounterByPV(mountRequest.MountDevice) + mounter, err := c.getMounterByPV(mountRequest) if err != nil { return "", c.logger.ErrorRet(err, "getMounterByPV failed") } @@ -502,6 +527,7 @@ func (c *Controller) doAfterMount(mountRequest k8sresources.FlexVolumeMountReque */ + defer c.logger.Trace(logs.DEBUG)() var k8sPVDirectoryPath string var err error @@ -562,30 +588,30 @@ func (c *Controller) doUnmountScbe(unmountRequest k8sresources.FlexVolumeUnmount defer c.logger.Trace(logs.DEBUG)() pvName := path.Base(unmountRequest.MountPath) - getVolumeRequest := resources.GetVolumeRequest{Name: pvName} + getVolumeRequest := resources.GetVolumeRequest{Name: pvName, Context: unmountRequest.Context} volume, err := c.Client.GetVolume(getVolumeRequest) // TODO idempotent, if volume not exist then log warning and return success - mounter, err := c.getMounterForBackend(volume.Backend) + mounter, err := c.getMounterForBackend(volume.Backend, unmountRequest.Context) if err != nil { err = fmt.Errorf("Error determining mounter for volume: %s", err.Error()) return c.logger.ErrorRet(err, "failed") } - getVolumeConfigRequest := resources.GetVolumeConfigRequest{Name: pvName} + getVolumeConfigRequest := resources.GetVolumeConfigRequest{Name: pvName, Context: unmountRequest.Context} volumeConfig, err := c.Client.GetVolumeConfig(getVolumeConfigRequest) if err != nil { err = fmt.Errorf("Error unmount for volume: %s", err.Error()) return c.logger.ErrorRet(err, "Client.GetVolumeConfig failed") } - ubUnmountRequest := resources.UnmountRequest{VolumeConfig: volumeConfig} + ubUnmountRequest := resources.UnmountRequest{VolumeConfig: volumeConfig, Context: unmountRequest.Context} err = mounter.Unmount(ubUnmountRequest) if err != nil { return c.logger.ErrorRet(err, "mounter.Unmount failed") } - c.logger.Debug(fmt.Sprintf("Removing the slink [%s] to the real mountpoint [%s]", unmountRequest.MountPath, realMountPoint)) + c.logger.Debug(fmt.Sprintf("[%s] to the real mountpoint [%s]", unmountRequest.MountPath, realMountPoint)) // TODO idempotent, don't fail if slink not exist. But double check its slink, if not then fail with error. err = c.exec.Remove(unmountRequest.MountPath) if err != nil { @@ -597,64 +623,64 @@ func (c *Controller) doUnmountScbe(unmountRequest k8sresources.FlexVolumeUnmount } func (c *Controller) doAfterDetach(detachRequest k8sresources.FlexVolumeDetachRequest) error { - defer c.logger.Trace(logs.DEBUG)() - - getVolumeRequest := resources.GetVolumeRequest{Name: detachRequest.Name} - volume, err := c.Client.GetVolume(getVolumeRequest) - mounter, err := c.getMounterForBackend(volume.Backend) - if err != nil { - err = fmt.Errorf("Error determining mounter for volume: %s", err.Error()) - return c.logger.ErrorRet(err, "failed") - } - - getVolumeConfigRequest := resources.GetVolumeConfigRequest{Name: detachRequest.Name} - volumeConfig, err := c.Client.GetVolumeConfig(getVolumeConfigRequest) - if err != nil { - err = fmt.Errorf("Error for volume: %s", err.Error()) - return c.logger.ErrorRet(err, "Client.GetVolumeConfig failed") - } - - afterDetachRequest := resources.AfterDetachRequest{VolumeConfig: volumeConfig} - if err := mounter.ActionAfterDetach(afterDetachRequest); err != nil { - err = fmt.Errorf("Error execute action after detaching the volume : %#v", err) - return c.logger.ErrorRet(err, "mounter.ActionAfterDetach failed") - } - - return nil + defer c.logger.Trace(logs.DEBUG)() + + getVolumeRequest := resources.GetVolumeRequest{Name: detachRequest.Name, Context: detachRequest.Context} + volume, err := c.Client.GetVolume(getVolumeRequest) + mounter, err := c.getMounterForBackend(volume.Backend, detachRequest.Context) + if err != nil { + err = fmt.Errorf("Error determining mounter for volume: %s", err.Error()) + return c.logger.ErrorRet(err, "failed") + } + + getVolumeConfigRequest := resources.GetVolumeConfigRequest{Name: detachRequest.Name, Context: detachRequest.Context} + volumeConfig, err := c.Client.GetVolumeConfig(getVolumeConfigRequest) + if err != nil { + err = fmt.Errorf("Error for volume: %s", err.Error()) + return c.logger.ErrorRet(err, "Client.GetVolumeConfig failed") + } + + afterDetachRequest := resources.AfterDetachRequest{VolumeConfig: volumeConfig, Context: detachRequest.Context} + if err := mounter.ActionAfterDetach(afterDetachRequest); err != nil { + err = fmt.Errorf("Error execute action after detaching the volume : %#v", err) + return c.logger.ErrorRet(err, "mounter.ActionAfterDetach failed") + } + + return nil } func (c *Controller) doUnmountSsc(unmountRequest k8sresources.FlexVolumeUnmountRequest, realMountPoint string) error { - defer c.logger.Trace(logs.DEBUG)() - - listVolumeRequest := resources.ListVolumesRequest{} - volumes, err := c.Client.ListVolumes(listVolumeRequest) - if err != nil { - err = fmt.Errorf("Error getting the volume list from ubiquity server %#v", err) - return c.logger.ErrorRet(err, "failed") - } - - volume, err := getVolumeForMountpoint(unmountRequest.MountPath, volumes) - if err != nil { - err = fmt.Errorf( - "Error finding the volume with mountpoint [%s] from the list of ubiquity volumes %#v. Error is : %#v", - unmountRequest.MountPath, - volumes, - err) - return c.logger.ErrorRet(err, "failed") - } - - detachRequest := resources.DetachRequest{Name: volume.Name} - err = c.Client.Detach(detachRequest) - if err != nil && err.Error() != "fileset not linked" { - err = fmt.Errorf( - "Failed to unmount volume [%s] on mountpoint [%s]. Error: %#v", - volume.Name, - unmountRequest.MountPath, - err) - return c.logger.ErrorRet(err, "failed") - } - - return nil + defer c.logger.Trace(logs.DEBUG)() + + listVolumeRequest := resources.ListVolumesRequest{Context: unmountRequest.Context} + volumes, err := c.Client.ListVolumes(listVolumeRequest) + if err != nil { + err = fmt.Errorf("Error getting the volume list from ubiquity server %#v", err) + return c.logger.ErrorRet(err, "failed") + } + + volume, err := getVolumeForMountpoint(unmountRequest.MountPath, volumes) + if err != nil { + err = fmt.Errorf( + "Error finding the volume with mountpoint [%s] from the list of ubiquity volumes %#v. Error is : %#v", + unmountRequest.MountPath, + volumes, + err) + return c.logger.ErrorRet(err, "failed") + } + + detachRequest := resources.DetachRequest{Name: volume.Name, Context: unmountRequest.Context} + err = c.Client.Detach(detachRequest) + if err != nil && err.Error() != "fileset not linked" { + err = fmt.Errorf( + "Failed to unmount volume [%s] on mountpoint [%s]. Error: %#v", + volume.Name, + unmountRequest.MountPath, + err) + return c.logger.ErrorRet(err, "failed") + } + + return nil } func (c *Controller) doActivate(activateRequest resources.ActivateRequest) error { @@ -676,7 +702,7 @@ func (c *Controller) doAttach(attachRequest k8sresources.FlexVolumeAttachRequest return c.logger.ErrorRet(&k8sVersionNotSupported{attachRequest.Version}, "failed") } - ubAttachRequest := resources.AttachRequest{Name: attachRequest.Name, Host: getHost(attachRequest.Host)} + ubAttachRequest := resources.AttachRequest{Name: attachRequest.Name, Host: getHost(attachRequest.Host), Context: attachRequest.Context} _, err := c.Client.Attach(ubAttachRequest) if err != nil { return c.logger.ErrorRet(err, "Client.Attach failed") @@ -691,7 +717,7 @@ func (c *Controller) doDetach(detachRequest k8sresources.FlexVolumeDetachRequest if checkIfAttached { opts := make(map[string]string) opts["volumeName"] = detachRequest.Name - isAttachedRequest := k8sresources.FlexVolumeIsAttachedRequest{Name: "", Host: detachRequest.Host, Opts: opts} + isAttachedRequest := k8sresources.FlexVolumeIsAttachedRequest{Name: "", Host:detachRequest.Host, Opts: opts, Context: detachRequest.Context} isAttached, err := c.doIsAttached(isAttachedRequest) if err != nil { return c.logger.ErrorRet(err, "failed") @@ -704,14 +730,14 @@ func (c *Controller) doDetach(detachRequest k8sresources.FlexVolumeDetachRequest if host == "" { // only when triggered during unmount var err error - host, err = c.getHostAttached(detachRequest.Name) + host, err = c.getHostAttached(detachRequest.Name, detachRequest.Context) if err != nil { return c.logger.ErrorRet(err, "getHostAttached failed") } } // TODO idempotent, don't trigger Detach if host is empty (even after getHostAttached) - ubDetachRequest := resources.DetachRequest{Name: detachRequest.Name, Host: host} + ubDetachRequest := resources.DetachRequest{Name: detachRequest.Name, Host: host, Context: detachRequest.Context} err := c.Client.Detach(ubDetachRequest) if err != nil { return c.logger.ErrorRet(err, "failed") @@ -729,7 +755,7 @@ func (c *Controller) doIsAttached(isAttachedRequest k8sresources.FlexVolumeIsAtt return false, c.logger.ErrorRet(err, "failed") } - attachTo, err := c.getHostAttached(volName) + attachTo, err := c.getHostAttached(volName, isAttachedRequest.Context) if err != nil { return false, c.logger.ErrorRet(err, "getHostAttached failed") } @@ -739,10 +765,10 @@ func (c *Controller) doIsAttached(isAttachedRequest k8sresources.FlexVolumeIsAtt return isAttached, nil } -func (c *Controller) getHostAttached(volName string) (string, error) { +func (c *Controller) getHostAttached(volName string, requestContext resources.RequestContext) (string, error) { defer c.logger.Trace(logs.DEBUG)() - getVolumeConfigRequest := resources.GetVolumeConfigRequest{Name: volName} + getVolumeConfigRequest := resources.GetVolumeConfigRequest{Name: volName, Context: requestContext} volumeConfig, err := c.Client.GetVolumeConfig(getVolumeConfigRequest) if err != nil { return "", c.logger.ErrorRet(err, "Client.GetVolumeConfig failed") diff --git a/glide.yaml b/glide.yaml index 246a69d54..676eb6328 100644 --- a/glide.yaml +++ b/glide.yaml @@ -9,7 +9,7 @@ import: subpackages: - lib - package: github.com/IBM/ubiquity - version: dev + version: fix/UB-1099_add_request_id_to_all_logs subpackages: - remote - resources diff --git a/resources/resources.go b/resources/resources.go index 33da6a74a..1b24fc5f4 100644 --- a/resources/resources.go +++ b/resources/resources.go @@ -1,5 +1,7 @@ package resources +import "github.com/IBM/ubiquity/resources" + const KubernetesVersion_1_5 = "1.5" const KubernetesVersion_1_6OrLater = "atLeast1.6" const ProvisionerName = "ubiquity/flex" @@ -31,10 +33,12 @@ type FlexVolumeMountRequest struct { MountDevice string `json:"name"` Opts map[string]string `json:"opts"` Version string `json:"version"` + Context resources.RequestContext } type FlexVolumeUnmountRequest struct { MountPath string `json:"mountPath"` + Context resources.RequestContext } type FlexVolumeAttachRequest struct { @@ -42,32 +46,38 @@ type FlexVolumeAttachRequest struct { Host string `json:"host"` Opts map[string]string `json:"opts"` Version string `json:"version"` + Context resources.RequestContext } type FlexVolumeWaitForAttachRequest struct { - Name string `json:"name"` - Opts map[string]string `json:"opts"` + Name string `json:"name"` + Opts map[string]string `json:"opts"` + Context resources.RequestContext } type FlexVolumeDetachRequest struct { Name string `json:"name"` Host string `json:"host"` Version string `json:"version"` + Context resources.RequestContext } type FlexVolumeIsAttachedRequest struct { - Name string `json:"name"` - Host string `json:"host"` - Opts map[string]string `json:"opts"` + Name string `json:"name"` + Host string `json:"host"` + Opts map[string]string `json:"opts"` + Context resources.RequestContext } type FlexVolumeMountDeviceRequest struct { - Name string `json:"name"` - Path string `json:"path"` - Opts map[string]string `json:"opts"` + Name string `json:"name"` + Path string `json:"path"` + Opts map[string]string `json:"opts"` + Context resources.RequestContext } type FlexVolumeUnmountDeviceRequest struct { - Name string `json:"name"` + Name string `json:"name"` + Context resources.RequestContext } type FlexVolumeGetVolumeNameRequest struct { diff --git a/utils/utils.go b/utils/utils.go index f9dce298a..bcde36048 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -1,10 +1,11 @@ package utils import ( - "github.com/IBM/ubiquity/resources" "os" "strconv" "strings" + + "github.com/IBM/ubiquity/resources" ) func LoadConfig() (resources.UbiquityPluginConfig, error) { diff --git a/volume/provision.go b/volume/provision.go index bd8f21dec..ff275c998 100644 --- a/volume/provision.go +++ b/volume/provision.go @@ -26,6 +26,7 @@ import ( k8sresources "github.com/IBM/ubiquity-k8s/resources" "github.com/IBM/ubiquity/resources" + "github.com/IBM/ubiquity/utils/logs" "github.com/kubernetes-incubator/external-storage/lib/controller" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" @@ -63,6 +64,7 @@ func NewFlexProvisioner(logger *log.Logger, ubiquityClient resources.StorageClie func newFlexProvisionerInternal(logger *log.Logger, ubiquityClient resources.StorageClient, config resources.UbiquityPluginConfig) (*flexProvisioner, error) { var identity types.UID identityPath := path.Join(config.LogPath, identityFile) + request_context := logs.GetNewRequestContext() if _, err := os.Stat(identityPath); os.IsNotExist(err) { identity = uuid.NewUUID() err := ioutil.WriteFile(identityPath, []byte(identity), 0600) @@ -77,7 +79,7 @@ func newFlexProvisionerInternal(logger *log.Logger, ubiquityClient resources.Sto identity = types.UID(strings.TrimSpace(string(read))) } provisioner := &flexProvisioner{ - logger: logger, + logger: logs.GetLogger(), identity: identity, ubiquityClient: ubiquityClient, ubiquityConfig: config, @@ -87,15 +89,15 @@ func newFlexProvisionerInternal(logger *log.Logger, ubiquityClient resources.Sto nodeEnv: nodeEnv, } - activateRequest := resources.ActivateRequest{Backends: config.Backends} - logger.Printf("activating backend %s \n", config.Backends) + activateRequest := resources.ActivateRequest{Backends: config.Backends, Context: request_context} + logger.Printf("activating backend %s\n", config.Backends) err := provisioner.ubiquityClient.Activate(activateRequest) return provisioner, err } type flexProvisioner struct { - logger *log.Logger + logger logs.Logger identity types.UID // Whether the provisioner is running out of cluster and so cannot rely on // the existence of any of the pod, service, namespace, node env variables. @@ -116,6 +118,11 @@ type flexProvisioner struct { // Provision creates a volume i.e. the storage asset and returns a PV object for // the volume. func (p *flexProvisioner) Provision(options controller.VolumeOptions) (*v1.PersistentVolume, error) { + request_context := logs.GetNewRequestContext() + go_id := logs.GetGoID() + logs.GoIdToRequestIdMap.Store(go_id, request_context) + defer logs.GetDeleteFromMapFunc(go_id) + defer p.logger.Trace(logs.DEBUG)() if options.PVC == nil { return nil, fmt.Errorf("options missing PVC %#v", options) } @@ -130,10 +137,11 @@ func (p *flexProvisioner) Provision(options controller.VolumeOptions) (*v1.Persi if !exists { return nil, fmt.Errorf("options.PVC.Spec.Resources.Requests does not contain capacity") } - fmt.Printf("PVC with capacity %d", capacity.Value()) + msg := fmt.Sprintf("PVC with capacity %d.", capacity.Value()) + p.logger.Info(msg) capacityMB := capacity.Value() / (1024 * 1024) - volume_details, err := p.createVolume(options, capacityMB) + volume_details, err := p.createVolume(options, capacityMB, request_context) if err != nil { return nil, err } @@ -172,24 +180,27 @@ func (p *flexProvisioner) Provision(options controller.VolumeOptions) (*v1.Persi // Delete removes the directory that was created by Provision backing the given // PV. func (p *flexProvisioner) Delete(volume *v1.PersistentVolume) error { - msg := fmt.Sprintf("Delete volume name [%s]", volume.Name) - p.logger.Printf("ENTER : " + msg) - defer p.logger.Printf("EXIT : " + msg) + requestContext := logs.GetNewRequestContext() + go_id := logs.GetGoID() + logs.GoIdToRequestIdMap.Store(go_id, requestContext) + defer logs.GetDeleteFromMapFunc(go_id) + defer p.logger.Trace(logs.DEBUG, logs.Args{{"volume name", volume.Name}})() if volume.Name == "" { return fmt.Errorf("volume name cannot be empty %#v", volume) } if volume.Spec.PersistentVolumeReclaimPolicy != v1.PersistentVolumeReclaimRetain { - getVolumeRequest := resources.GetVolumeRequest{Name: volume.Name} + getVolumeRequest := resources.GetVolumeRequest{Name: volume.Name, Context: requestContext} volume, err := p.ubiquityClient.GetVolume(getVolumeRequest) if err != nil { fmt.Printf("error-retrieving-volume-info") return err } - removeVolumeRequest := resources.RemoveVolumeRequest{Name: volume.Name} + removeVolumeRequest := resources.RemoveVolumeRequest{Name: volume.Name, Context: requestContext} err = p.ubiquityClient.RemoveVolume(removeVolumeRequest) if err != nil { + p.logger.Info("error removing volume") return err } return nil @@ -199,10 +210,8 @@ func (p *flexProvisioner) Delete(volume *v1.PersistentVolume) error { return nil } -func (p *flexProvisioner) createVolume(options controller.VolumeOptions, capacity int64) (map[string]string, error) { - msg := fmt.Sprintf("Create volume name [%s]", options.PVName) - p.logger.Printf("ENTER : " + msg) - defer p.logger.Printf("EXIT : " + msg) +func (p *flexProvisioner) createVolume(options controller.VolumeOptions, capacity int64, requestContext resources.RequestContext) (map[string]string, error) { + defer p.logger.Trace(logs.DEBUG, logs.Args{{"volume name", options.PVName}})() ubiquityParams := make(map[string]interface{}) if capacity != 0 { @@ -217,16 +226,16 @@ func (p *flexProvisioner) createVolume(options controller.VolumeOptions, capacit return nil, fmt.Errorf("backend is not specified") } b := backendName.(string) - createVolumeRequest := resources.CreateVolumeRequest{Name: options.PVName, Backend: b, Opts: ubiquityParams} + createVolumeRequest := resources.CreateVolumeRequest{Name: options.PVName, Backend: b, Opts: ubiquityParams, Context: requestContext} err := p.ubiquityClient.CreateVolume(createVolumeRequest) if err != nil { - return nil, fmt.Errorf("error creating volume: %v", err) + return nil, fmt.Errorf("error creating volume: %v.", err) } - getVolumeConfigRequest := resources.GetVolumeConfigRequest{Name: options.PVName} + getVolumeConfigRequest := resources.GetVolumeConfigRequest{Name: options.PVName, Context: requestContext} volumeConfig, err := p.ubiquityClient.GetVolumeConfig(getVolumeConfigRequest) if err != nil { - return nil, fmt.Errorf("error getting volume config details: %v", err) + return nil, fmt.Errorf("error getting volume config details: %v ", err) } flexVolumeConfig := make(map[string]string) diff --git a/volume/provision_suite_test.go b/volume/provision_suite_test.go index 6a693fd29..f70ded196 100644 --- a/volume/provision_suite_test.go +++ b/volume/provision_suite_test.go @@ -21,6 +21,7 @@ import ( "log" "os" + "github.com/IBM/ubiquity/utils/logs" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" @@ -32,6 +33,7 @@ var logFile *os.File func TestController(t *testing.T) { RegisterFailHandler(Fail) + defer logs.InitStdoutLogger(logs.DEBUG)() RunSpecs(t, "Provisioner Suite") } From 7f6f6c0916a22c423632b78999307f9f5ea4e03e Mon Sep 17 00:00:00 2001 From: Olga Shtivelman Date: Wed, 13 Jun 2018 11:17:09 +0300 Subject: [PATCH 08/40] Return glide.yaml - ubiquity version to dev --- glide.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/glide.yaml b/glide.yaml index 676eb6328..246a69d54 100644 --- a/glide.yaml +++ b/glide.yaml @@ -9,7 +9,7 @@ import: subpackages: - lib - package: github.com/IBM/ubiquity - version: fix/UB-1099_add_request_id_to_all_logs + version: dev subpackages: - remote - resources From a13bc08c6d5061fdfc706508627ac694f5d90c1b Mon Sep 17 00:00:00 2001 From: Isaac Beckman Date: Thu, 21 Jun 2018 11:15:48 +0300 Subject: [PATCH 09/40] Update to k8s 1.9 in glide (#192) * Update to k8s 1.9 in glide * update k82-incubator/external-storage --- glide.yaml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/glide.yaml b/glide.yaml index 246a69d54..c9b6ff9d4 100644 --- a/glide.yaml +++ b/glide.yaml @@ -5,7 +5,7 @@ import: - package: github.com/jessevdk/go-flags version: f88afde2fa19a30cf50ba4b05b3d13bc6bae3079 - package: github.com/kubernetes-incubator/external-storage - version: 094dd501fc4ff313fb872e90e19f774819f192b7 + version: 92295a30e0ec7da80c41c1f50f9301f3adee4556 subpackages: - lib - package: github.com/IBM/ubiquity @@ -16,7 +16,7 @@ import: - utils - fakes - package: k8s.io/apimachinery - version: release-1.8 + version: kubernetes-1.9.8 subpackages: - pkg/api/errors - pkg/api/resource @@ -30,7 +30,7 @@ import: - pkg/util/wait - pkg/watch - package: k8s.io/client-go - version: release-5.0 + version: v6.0.0 subpackages: - kubernetes - kubernetes/typed/core/v1 @@ -41,9 +41,9 @@ import: - tools/remotecommand - tools/reference - package: k8s.io/api - version: release-1.8 + version: kubernetes-1.9.8 - package: k8s.io/kubernetes - version: release-1.8 + version: v1.9.8 subpackages: - pkg/util/goroutinemap - pkg/util/version From b5a2162f3bc40829c954678fc77428286def3463 Mon Sep 17 00:00:00 2001 From: shay-berman Date: Tue, 26 Jun 2018 16:43:09 +0300 Subject: [PATCH 10/40] Fix/idempotent umount for slink not exist and PV not exist (#193) * Fix idempotent issues in Unmount flex (slink exist, removal and no PV) + refactoring 1. fix idempotent1 if PV not exist in ubiqutiy DB then finish unmount with success 2. fix idempotent2 if slink not exist then skip unmount and go to detach stage (Add checkSlinkBeforeUmount func to identify the idempotent state and other abnormal slink states) 3. fix idempotent3 if slink not exist then do not try to delete it. 4. Refactor - fix backend identification by ubiquity server call rather then check by mountpoint path 5. Refactor - Unmount with doUnmount and removal the different flow for SSc (because it should be the same flow) * Add unit testing for Unmount * Refactor to reuse failureFlexVolumeResponse func * Fixed Olga code review comments --- controller/controller.go | 349 +++++++++++++++++++--------------- controller/controller_test.go | 282 +++++++++++++++++++++++++++ controller/errors.go | 35 ++++ 3 files changed, 514 insertions(+), 152 deletions(-) diff --git a/controller/controller.go b/controller/controller.go index 3a07681ec..c24cf7129 100644 --- a/controller/controller.go +++ b/controller/controller.go @@ -18,20 +18,20 @@ package controller import ( "fmt" - "github.com/IBM/ubiquity/utils/logs" "log" "os" "path" + "path/filepath" "strings" + "time" k8sresources "github.com/IBM/ubiquity-k8s/resources" "github.com/IBM/ubiquity/remote" "github.com/IBM/ubiquity/remote/mounter" "github.com/IBM/ubiquity/resources" "github.com/IBM/ubiquity/utils" + "github.com/IBM/ubiquity/utils/logs" "github.com/nightlyone/lockfile" - "path/filepath" - "time" ) const FlexSuccessStr = "Success" @@ -114,15 +114,9 @@ func (c *Controller) TestUbiquity(config resources.UbiquityPluginConfig) k8sreso err := c.doActivate(activateRequest) if err != nil { - response = k8sresources.FlexVolumeResponse{ - Status: "Failure", - Message: fmt.Sprintf("Test ubiquity failed %#v ", err), - } + response = c.failureFlexVolumeResponse(err, "Test ubiquity failed") } else { - response = k8sresources.FlexVolumeResponse{ - Status: "Success", - Message: "Test ubiquity successfully", - } + response = c.successFlexVolumeResponse("Test ubiquity successfully") } c.logger.Debug("", logs.Args{{"response", response}}) @@ -140,15 +134,10 @@ func (c *Controller) Attach(attachRequest k8sresources.FlexVolumeAttachRequest) err := c.doAttach(attachRequest) if err != nil { - msg := fmt.Sprintf("Failed to attach volume [%s], Error: %#v", attachRequest.Name, err) - response = k8sresources.FlexVolumeResponse{ - Status: "Failure", - Message: msg, - } + msg := fmt.Sprintf("Failed to attach volume [%s]", attachRequest.Name) + response = c.failureFlexVolumeResponse(err, msg) } else { - response = k8sresources.FlexVolumeResponse{ - Status: "Success", - } + response = c.successFlexVolumeResponse("") } c.logger.Debug("", logs.Args{{"response", response}}) @@ -197,11 +186,8 @@ func (c *Controller) IsAttached(isAttachedRequest k8sresources.FlexVolumeIsAttac isAttached, err := c.doIsAttached(isAttachedRequest) if err != nil { - msg := fmt.Sprintf("Failed to check IsAttached volume [%s], Error: %#v", isAttachedRequest.Name, err) - response = k8sresources.FlexVolumeResponse{ - Status: "Failure", - Message: msg, - } + msg := fmt.Sprintf("Failed to check IsAttached volume [%s]", isAttachedRequest.Name) + response = c.failureFlexVolumeResponse(err, msg) } else { response = k8sresources.FlexVolumeResponse{ Status: "Success", @@ -293,17 +279,11 @@ func (c *Controller) Mount(mountRequest k8sresources.FlexVolumeMountRequest) k8s // TODO check if volume exist first and what its backend type mountedPath, err := c.doMount(mountRequest) if err != nil { - response = k8sresources.FlexVolumeResponse{ - Status: "Failure", - Message: err.Error(), - } + response = c.failureFlexVolumeResponse(err, "") } else { err = c.doAfterMount(mountRequest, mountedPath) if err != nil { - response = k8sresources.FlexVolumeResponse{ - Status: "Failure", - Message: err.Error(), - } + response = c.failureFlexVolumeResponse(err, "") } else { response = k8sresources.FlexVolumeResponse{ Status: "Success", @@ -315,14 +295,126 @@ func (c *Controller) Mount(mountRequest k8sresources.FlexVolumeMountRequest) k8s return response } +func (c *Controller) successFlexVolumeResponse(msg string) k8sresources.FlexVolumeResponse { + defer c.logger.Trace(logs.DEBUG)() + response := k8sresources.FlexVolumeResponse{ + Status: FlexSuccessStr, + Message: msg, + } + c.logger.Info(fmt.Sprintf("%#v", response)) + return response +} + +func (c *Controller) failureFlexVolumeResponse(err error, additionalMsg string) k8sresources.FlexVolumeResponse { + defer c.logger.Trace(logs.DEBUG)() + + response := k8sresources.FlexVolumeResponse{ + Status: FlexFailureStr, + Message: additionalMsg + err.Error(), + } + c.logger.Error(fmt.Sprintf("%#v", response)) + return response +} + +func (c *Controller) checkSlinkBeforeUmount(k8sPVDirectoryPath string, realMountedPath string) (bool, error) { + /* + Return + true, nil : slink exist as expected + false, nil : slink not exist, which indicate for idempotent issue + true, error : its slink but error during evaluate it or its slink but not to the right place + false, error : its something different then slink + */ + defer c.logger.Trace(logs.DEBUG)() + + // Identify the PV directory by using Lstat and then handle all idempotent cases (use Lstat to get the dir or slink detail and not the evaluation of it) + fileInfo, err := c.exec.Lstat(k8sPVDirectoryPath) + if err != nil { + if c.exec.IsNotExist(err) { + // The k8s PV directory not exist (its a rare case and indicate on idempotent flow) + c.logger.Info("PV directory(k8s-mountpoint) does not exist.", logs.Args{{"k8s-mountpoint", k8sPVDirectoryPath}, {"should-point-to-mountpoint", realMountedPath}}) // TODO change it to warning + return false, nil // Idempotent flow + } else { + // Maybe some permissions issue + return false, c.logger.ErrorRet(err, "Controller: failed to identify PV directory(k8s-mountpoint)", logs.Args{{"k8s-mountpoint", k8sPVDirectoryPath}}) + } + } else if c.exec.IsSlink(fileInfo) { + // Its already slink so check if slink is ok and skip else raise error + evalSlink, err := c.exec.EvalSymlinks(k8sPVDirectoryPath) + if err != nil { + return true, c.logger.ErrorRet(err, "Controller: Idempotent - failed eval the slink of PV directory(k8s-mountpoint)", logs.Args{{"k8s-mountpoint", k8sPVDirectoryPath}}) + } + if evalSlink == realMountedPath { + c.logger.Info("PV directory(k8s-mountpoint) is slink that point to the right mountpoint.", logs.Args{{"k8s-mountpoint", k8sPVDirectoryPath}, {"mountpoint", realMountedPath}}) + return true, nil // Good path + } else { + // Very edge case, where the slink is point to wrong mountpoint + return true, c.logger.ErrorRet( + &wrongSlinkError{slink: k8sPVDirectoryPath, wrongPointTo: evalSlink, expectedPointTo: realMountedPath}, + "failed") + } + } else { + return false, c.logger.ErrorRet(&k8sPVDirectoryIsNotSlinkError{k8sPVDirectoryPath, fileInfo}, "failed") + } + +} + +func (c *Controller) getRealMountpointForPvByBackend(volumeBackend string, volumeConfig map[string]interface{}) (string, error) { + // TODO we should create agnostic function based on backend that returns the real mountpoint + defer c.logger.Trace(logs.DEBUG)() + if volumeBackend == resources.SCBE { + return fmt.Sprintf(resources.PathToMountUbiquityBlockDevices, volumeConfig["Wwn"].(string)), nil + } else if volumeBackend == resources.SpectrumScale { + return "", &BackendNotImplementedGetRealMountpointError{Backend: volumeBackend} + } else { + return "", &PvBackendNotSupportedError{Backend: volumeBackend} + } +} +func (c *Controller) doUnmount(k8sPVDirectoryPath string, volumeBackend string, volumeConfig map[string]interface{}, mounter resources.Mounter) error { + /* + Call to unmount mounter if slink exist and then delete the slink + if slink not exist skip unmount (indicate for idempotent flow). + */ + defer c.logger.Trace(logs.DEBUG)() + var realMountedPath string + var slinkExist bool + var err error + if realMountedPath, err = c.getRealMountpointForPvByBackend(volumeBackend, volumeConfig); err != nil { + return c.logger.ErrorRet(err, "getRealMountpointForPvByBackend failed") + } + + // ------------------------------------ + if slinkExist, err = c.checkSlinkBeforeUmount(k8sPVDirectoryPath, realMountedPath); err != nil { + return c.logger.ErrorRet(err, "checkSlinkBeforeUmount failed") + } + if slinkExist { + + ubUnmountRequest := resources.UnmountRequest{VolumeConfig: volumeConfig} // TODO need to add to the request the real mountpoint to umount + if err := mounter.Unmount(ubUnmountRequest); err != nil { + return c.logger.ErrorRet(err, "mounter.Unmount failed") + } + + c.logger.Debug(fmt.Sprintf("Removing the slink [%s] to the real mountpoint [%s]", k8sPVDirectoryPath, realMountedPath)) + if err := c.exec.Remove(k8sPVDirectoryPath); err != nil { + // the slink must exist at this point + return c.logger.ErrorRet(err, "fail to remove slink "+k8sPVDirectoryPath) + } + } else { + c.logger.Info("PV directory(k8s-mountpoint) is not exist. Idempotent - skip unmount flow", + logs.Args{{"k8s-mountpoint", k8sPVDirectoryPath}, {"should-point-to-mountpoint", realMountedPath}}) // TODO change it to warning + } + return nil // Finish successfully to umount +} + //Unmount methods unmounts the volume from the pod func (c *Controller) Unmount(unmountRequest k8sresources.FlexVolumeUnmountRequest) k8sresources.FlexVolumeResponse { go_id := logs.GetGoID() logs.GoIdToRequestIdMap.Store(go_id, unmountRequest.Context) defer logs.GetDeleteFromMapFunc(go_id) - defer c.logger.Trace(logs.DEBUG)() + defer c.logger.Trace(logs.DEBUG, logs.Args{{"unmountRequest", unmountRequest}})() + k8sPVDirectoryPath := unmountRequest.MountPath + // locking for concurrent rescans and reduce rescans if no need - c.logger.Debug("Ask for unmountFlock for mountpath", logs.Args{{"mountpath", unmountRequest.MountPath}}) + c.logger.Debug("Ask for unmountFlock for mountpath", logs.Args{{"mountpath", k8sPVDirectoryPath}}) for { err := c.unmountFlock.TryLock() if err == nil { @@ -331,55 +423,45 @@ func (c *Controller) Unmount(unmountRequest k8sresources.FlexVolumeUnmountReques c.logger.Debug("unmountFlock.TryLock failed", logs.Args{{"error", err}}) time.Sleep(time.Duration(500 * time.Millisecond)) } - c.logger.Debug("Got unmountFlock for mountpath", logs.Args{{"mountpath", unmountRequest.MountPath}}) + c.logger.Debug("Got unmountFlock for mountpath", logs.Args{{"mountpath", k8sPVDirectoryPath}}) defer c.unmountFlock.Unlock() - defer c.logger.Debug("Released unmountFlock for mountpath", logs.Args{{"mountpath", unmountRequest.MountPath}}) - + defer c.logger.Debug("Released unmountFlock for mountpath", logs.Args{{"mountpath", k8sPVDirectoryPath}}) - var response k8sresources.FlexVolumeResponse - c.logger.Debug("", logs.Args{{"request", unmountRequest}}) + var mounter resources.Mounter + var volumeConfig map[string]interface{} + var volume resources.Volume var err error - // Validate that the mountpoint is a symlink as ubiquity expect it to be - realMountPoint, err := c.exec.EvalSymlinks(unmountRequest.MountPath) - // TODO idempotent, don't use EvalSymlinks to identify the backend, instead check the volume backend. In addition when we check the eval of the slink, if its not exist we should jump to detach (if its not slink then we should fail) + // GetVolume by pv name to identify if it exist in ubiquity DB and to receive the backend + pvName := path.Base(k8sPVDirectoryPath) // Assumption that the k8s mountpoint directory contains(basename) the pv name it self. + getVolumeRequest := resources.GetVolumeRequest{Name: pvName} + if volume, err = c.Client.GetVolume(getVolumeRequest); err != nil { + if strings.Contains(err.Error(), resources.VolumeNotFoundErrorMsg) { + warningMsg := fmt.Sprintf("%s (backend error=%v)", IdempotentUnmountSkipOnVolumeNotExistWarnigMsg, err) + c.logger.Info(warningMsg) // TODO later change to warning message + return c.successFlexVolumeResponse(warningMsg) + } + return c.failureFlexVolumeResponse(err, "") + } - if err != nil { - msg := fmt.Sprintf("Cannot execute umount because the mountPath [%s] is not a symlink as expected. Error: %#v", unmountRequest.MountPath, err) - c.logger.Error(msg) - return k8sresources.FlexVolumeResponse{Status: "Failure", Message: msg, Device: ""} + if mounter, err = c.getMounterForBackend(volume.Backend, unmountRequest.Context); err != nil { + return c.failureFlexVolumeResponse(err, "Error determining mounter for volume. ") } - ubiquityMountPrefix := fmt.Sprintf(resources.PathToMountUbiquityBlockDevices, "") - if strings.HasPrefix(realMountPoint, ubiquityMountPrefix) { - // SCBE backend flow - err = c.doUnmountScbe(unmountRequest, realMountPoint) - } else { - // SSC backend flow - err = c.doUnmountSsc(unmountRequest, realMountPoint) + getVolumeConfigRequest := resources.GetVolumeConfigRequest{Name: pvName} + if volumeConfig, err = c.Client.GetVolumeConfig(getVolumeConfigRequest); err != nil { + return c.failureFlexVolumeResponse(err, "Error unmount for volume. ") } - if err != nil { - response = k8sresources.FlexVolumeResponse{ - Status: "Failure", - Message: err.Error(), - } - } else { - err = c.doLegacyDetach(unmountRequest) - if err != nil { - response = k8sresources.FlexVolumeResponse{ - Status: "Failure", - Message: err.Error(), - } - } else { - response = k8sresources.FlexVolumeResponse{ - Status: "Success", - } - } + if err := c.doUnmount(k8sPVDirectoryPath, volume.Backend, volumeConfig, mounter); err != nil { + return c.failureFlexVolumeResponse(err, "") + } + // Do legacy detach (means trigger detach as part of the umount from the k8s node) + if err := c.doLegacyDetach(unmountRequest); err != nil { + return c.failureFlexVolumeResponse(err, "") } - c.logger.Debug("", logs.Args{{"response", response}}) - return response + return c.successFlexVolumeResponse("") } func (c *Controller) doLegacyDetach(unmountRequest k8sresources.FlexVolumeUnmountRequest) error { @@ -439,7 +521,7 @@ func (c *Controller) prepareUbiquityMountRequest(mountRequest k8sresources.FlexV return resources.MountRequest{}, c.logger.ErrorRet(err, "failed") } volumeMountpoint := fmt.Sprintf(resources.PathToMountUbiquityBlockDevices, wwn) - ubMountRequest := resources.MountRequest{Mountpoint: volumeMountpoint, VolumeConfig: volumeConfig, Context : mountRequest.Context} + ubMountRequest := resources.MountRequest{Mountpoint: volumeMountpoint, VolumeConfig: volumeConfig, Context: mountRequest.Context} return ubMountRequest, nil } @@ -527,14 +609,13 @@ func (c *Controller) doAfterMount(mountRequest k8sresources.FlexVolumeMountReque */ - defer c.logger.Trace(logs.DEBUG)() var k8sPVDirectoryPath string var err error k8sPVDirectoryPath = c.getK8sPVDirectoryByBackend(mountedPath, mountRequest.MountPath) - // Identify the PV directory by using Lstat and then handle all idempotend cases (use Lstat to get the dir or slink detail and not the evaluation of it) + // Identify the PV directory by using Lstat and then handle all idempotent cases (use Lstat to get the dir or slink detail and not the evaluation of it) fileInfo, err := c.exec.Lstat(k8sPVDirectoryPath) if err != nil { if c.exec.IsNotExist(err) { @@ -584,103 +665,66 @@ func (c *Controller) doAfterMount(mountRequest k8sresources.FlexVolumeMountReque return nil } -func (c *Controller) doUnmountScbe(unmountRequest k8sresources.FlexVolumeUnmountRequest, realMountPoint string) error { +func (c *Controller) doAfterDetach(detachRequest k8sresources.FlexVolumeDetachRequest) error { defer c.logger.Trace(logs.DEBUG)() - pvName := path.Base(unmountRequest.MountPath) - getVolumeRequest := resources.GetVolumeRequest{Name: pvName, Context: unmountRequest.Context} - + getVolumeRequest := resources.GetVolumeRequest{Name: detachRequest.Name, Context: detachRequest.Context} volume, err := c.Client.GetVolume(getVolumeRequest) - // TODO idempotent, if volume not exist then log warning and return success - mounter, err := c.getMounterForBackend(volume.Backend, unmountRequest.Context) + mounter, err := c.getMounterForBackend(volume.Backend, detachRequest.Context) if err != nil { err = fmt.Errorf("Error determining mounter for volume: %s", err.Error()) return c.logger.ErrorRet(err, "failed") } - getVolumeConfigRequest := resources.GetVolumeConfigRequest{Name: pvName, Context: unmountRequest.Context} + getVolumeConfigRequest := resources.GetVolumeConfigRequest{Name: detachRequest.Name, Context: detachRequest.Context} volumeConfig, err := c.Client.GetVolumeConfig(getVolumeConfigRequest) if err != nil { - err = fmt.Errorf("Error unmount for volume: %s", err.Error()) + err = fmt.Errorf("Error for volume: %s", err.Error()) return c.logger.ErrorRet(err, "Client.GetVolumeConfig failed") } - ubUnmountRequest := resources.UnmountRequest{VolumeConfig: volumeConfig, Context: unmountRequest.Context} - err = mounter.Unmount(ubUnmountRequest) - if err != nil { - return c.logger.ErrorRet(err, "mounter.Unmount failed") - } - - c.logger.Debug(fmt.Sprintf("[%s] to the real mountpoint [%s]", unmountRequest.MountPath, realMountPoint)) - // TODO idempotent, don't fail if slink not exist. But double check its slink, if not then fail with error. - err = c.exec.Remove(unmountRequest.MountPath) - if err != nil { - err = fmt.Errorf("fail to remove slink %s. Error %#v", unmountRequest.MountPath, err) - return c.logger.ErrorRet(err, "exec.Remove failed") + afterDetachRequest := resources.AfterDetachRequest{VolumeConfig: volumeConfig, Context: detachRequest.Context} + if err := mounter.ActionAfterDetach(afterDetachRequest); err != nil { + err = fmt.Errorf("Error execute action after detaching the volume : %#v", err) + return c.logger.ErrorRet(err, "mounter.ActionAfterDetach failed") } return nil } -func (c *Controller) doAfterDetach(detachRequest k8sresources.FlexVolumeDetachRequest) error { - defer c.logger.Trace(logs.DEBUG)() - - getVolumeRequest := resources.GetVolumeRequest{Name: detachRequest.Name, Context: detachRequest.Context} - volume, err := c.Client.GetVolume(getVolumeRequest) - mounter, err := c.getMounterForBackend(volume.Backend, detachRequest.Context) - if err != nil { - err = fmt.Errorf("Error determining mounter for volume: %s", err.Error()) - return c.logger.ErrorRet(err, "failed") - } - - getVolumeConfigRequest := resources.GetVolumeConfigRequest{Name: detachRequest.Name, Context: detachRequest.Context} - volumeConfig, err := c.Client.GetVolumeConfig(getVolumeConfigRequest) - if err != nil { - err = fmt.Errorf("Error for volume: %s", err.Error()) - return c.logger.ErrorRet(err, "Client.GetVolumeConfig failed") - } +func (c *Controller) doUnmountSsc(unmountRequest k8sresources.FlexVolumeUnmountRequest, realMountPoint string) error { + defer c.logger.Trace(logs.DEBUG)() + // TODO : double check why for SScale the function trigger detach instead of umount? in addition its bad practice to get all vols. + // Consider to delete this function since there is no need for special flow for UnMount for SSc. + listVolumeRequest := resources.ListVolumesRequest{} + volumes, err := c.Client.ListVolumes(listVolumeRequest) + if err != nil { + err = fmt.Errorf("Error getting the volume list from ubiquity server %#v", err) + return c.logger.ErrorRet(err, "failed") + } - afterDetachRequest := resources.AfterDetachRequest{VolumeConfig: volumeConfig, Context: detachRequest.Context} - if err := mounter.ActionAfterDetach(afterDetachRequest); err != nil { - err = fmt.Errorf("Error execute action after detaching the volume : %#v", err) - return c.logger.ErrorRet(err, "mounter.ActionAfterDetach failed") - } + volume, err := getVolumeForMountpoint(unmountRequest.MountPath, volumes) + if err != nil { + err = fmt.Errorf( + "Error finding the volume with mountpoint [%s] from the list of ubiquity volumes %#v. Error is : %#v", + unmountRequest.MountPath, + volumes, + err) + return c.logger.ErrorRet(err, "failed") + } - return nil -} + detachRequest := resources.DetachRequest{Name: volume.Name} + err = c.Client.Detach(detachRequest) + if err != nil && err.Error() != "fileset not linked" { + err = fmt.Errorf( + "Failed to unmount volume [%s] on mountpoint [%s]. Error: %#v", + volume.Name, + unmountRequest.MountPath, + err) + return c.logger.ErrorRet(err, "failed") + } -func (c *Controller) doUnmountSsc(unmountRequest k8sresources.FlexVolumeUnmountRequest, realMountPoint string) error { - defer c.logger.Trace(logs.DEBUG)() - - listVolumeRequest := resources.ListVolumesRequest{Context: unmountRequest.Context} - volumes, err := c.Client.ListVolumes(listVolumeRequest) - if err != nil { - err = fmt.Errorf("Error getting the volume list from ubiquity server %#v", err) - return c.logger.ErrorRet(err, "failed") - } - - volume, err := getVolumeForMountpoint(unmountRequest.MountPath, volumes) - if err != nil { - err = fmt.Errorf( - "Error finding the volume with mountpoint [%s] from the list of ubiquity volumes %#v. Error is : %#v", - unmountRequest.MountPath, - volumes, - err) - return c.logger.ErrorRet(err, "failed") - } - - detachRequest := resources.DetachRequest{Name: volume.Name, Context: unmountRequest.Context} - err = c.Client.Detach(detachRequest) - if err != nil && err.Error() != "fileset not linked" { - err = fmt.Errorf( - "Failed to unmount volume [%s] on mountpoint [%s]. Error: %#v", - volume.Name, - unmountRequest.MountPath, - err) - return c.logger.ErrorRet(err, "failed") - } - - return nil + return nil } func (c *Controller) doActivate(activateRequest resources.ActivateRequest) error { @@ -717,12 +761,13 @@ func (c *Controller) doDetach(detachRequest k8sresources.FlexVolumeDetachRequest if checkIfAttached { opts := make(map[string]string) opts["volumeName"] = detachRequest.Name - isAttachedRequest := k8sresources.FlexVolumeIsAttachedRequest{Name: "", Host:detachRequest.Host, Opts: opts, Context: detachRequest.Context} + isAttachedRequest := k8sresources.FlexVolumeIsAttachedRequest{Name: "", Host: detachRequest.Host, Opts: opts, Context: detachRequest.Context} isAttached, err := c.doIsAttached(isAttachedRequest) if err != nil { return c.logger.ErrorRet(err, "failed") } if !isAttached { + c.logger.Debug(fmt.Sprintf("Skip detach [%s] to host [%s] because its already detached.", detachRequest.Name, detachRequest.Host)) return nil } } diff --git a/controller/controller_test.go b/controller/controller_test.go index 4a1711249..1a10486b7 100644 --- a/controller/controller_test.go +++ b/controller/controller_test.go @@ -489,6 +489,288 @@ var _ = Describe("Controller", func() { Expect(mountResponse.Status).To(Equal(ctl.FlexFailureStr)) }) + }) + Context(".Unmount", func() { + It("should fail in GetVolume returns error that is not about volume not found in DB (Unmount)", func() { + fakeClient.GetVolumeReturns(resources.Volume{}, fmt.Errorf("just error")) + unmountRequest := k8sresources.FlexVolumeUnmountRequest{MountPath: "/k8s-dir-pod/pv1"} + + mountResponse := controller.Unmount(unmountRequest) + + Expect(fakeClient.GetVolumeCallCount()).To(Equal(1)) + Expect(mountResponse.Message).To(MatchRegexp(".*just error")) + Expect(mountResponse.Status).To(Equal(ctl.FlexFailureStr)) + }) + It("should return success if try to unmount PV that is not exist, idempotent issue (Unmount)", func() { + fakeClient.GetVolumeReturns(resources.Volume{}, &resources.VolumeNotFoundError{VolName: "pv1"}) + unmountRequest := k8sresources.FlexVolumeUnmountRequest{MountPath: "/k8s-dir-pod/pv1"} + + mountResponse := controller.Unmount(unmountRequest) + + Expect(fakeClient.GetVolumeCallCount()).To(Equal(1)) + Expect(mountResponse.Message).To(MatchRegexp(".*" + resources.VolumeNotFoundErrorMsg)) + Expect(mountResponse.Status).To(Equal(ctl.FlexSuccessStr)) + }) + It("should fail if cannot get mounter for the PV (doMount, GetMounterPerBackend)", func() { + errstr := "ERROR backend" + fakeClient.GetVolumeReturns(resources.Volume{Name: "pv1", Backend: "XXX", Mountpoint: "fake"}, nil) + fakeMounterFactory.GetMounterPerBackendReturns(fakeMounter, fmt.Errorf(errstr)) + controller = ctl.NewControllerWithClient(testLogger, ubiquityConfig, fakeClient, fakeExec, fakeMounterFactory) + unmountRequest := k8sresources.FlexVolumeUnmountRequest{MountPath: "/k8s-dir-pod/pv1"} + + response := controller.Unmount(unmountRequest) + + Expect(response.Device).To(Equal("")) + Expect(fakeClient.GetVolumeCallCount()).To(Equal(1)) + Expect(fakeMounterFactory.GetMounterPerBackendCallCount()).To(Equal(1)) + Expect(fakeClient.GetVolumeConfigCallCount()).To(Equal(0)) + Expect(response.Message).To(MatchRegexp(errstr)) + Expect(response.Status).To(Equal(ctl.FlexFailureStr)) + }) + It("should fail to prepareUbiquityMountRequest if GetVolumeConfig failed (doMount)", func() { + errstr := "fakeError" + fakeClient.GetVolumeReturns(resources.Volume{Name: "pv1", Backend: "aaaa", Mountpoint: "fake"}, nil) + byt := []byte(`{"":""}`) + var dat map[string]interface{} + if err := json.Unmarshal(byt, &dat); err != nil { + panic(err) + } + fakeClient.GetVolumeConfigReturns(dat, fmt.Errorf(errstr)) + unmountRequest := k8sresources.FlexVolumeUnmountRequest{MountPath: "/pod/pv1"} + + response := controller.Unmount(unmountRequest) + + Expect(fakeClient.GetVolumeCallCount()).To(Equal(1)) + Expect(fakeMounterFactory.GetMounterPerBackendCallCount()).To(Equal(1)) + Expect(fakeClient.GetVolumeConfigCallCount()).To(Equal(1)) + Expect(fakeMounter.UnmountCallCount()).To(Equal(0)) + Expect(response.Message).To(MatchRegexp(errstr)) + Expect(response.Status).To(Equal(ctl.FlexFailureStr)) + }) + It("should fail to doUnmount because volume has unknown backend type", func() { + fakeClient.GetVolumeReturns(resources.Volume{Name: "pv1", Backend: "aaaa", Mountpoint: "fake"}, nil) + byt := []byte(`{"":""}`) + var dat map[string]interface{} + if err := json.Unmarshal(byt, &dat); err != nil { + panic(err) + } + fakeClient.GetVolumeConfigReturns(dat, nil) + unmountRequest := k8sresources.FlexVolumeUnmountRequest{MountPath: "/pod/pv1"} + + response := controller.Unmount(unmountRequest) + + Expect(fakeClient.GetVolumeCallCount()).To(Equal(1)) + Expect(fakeMounterFactory.GetMounterPerBackendCallCount()).To(Equal(1)) + Expect(fakeClient.GetVolumeConfigCallCount()).To(Equal(1)) + Expect(fakeMounter.UnmountCallCount()).To(Equal(0)) + Expect(response.Message).To(MatchRegexp(ctl.PvBackendNotSupportedErrorStr)) + Expect(response.Status).To(Equal(ctl.FlexFailureStr)) + }) + Context(".Unmount checkSlinkBeforeUmount", func() { + var ( + errstrObj error + errstr string + wwn string + ) + BeforeEach(func() { + errstr = "fakerror" + errstrObj = fmt.Errorf(errstr) + fakeClient.GetVolumeReturns(resources.Volume{Name: "pv1", Backend: resources.SCBE, Mountpoint: "fake"}, nil) + wwn = "fake" + byt := []byte(`{"Wwn":"fake"}`) // TODO should use the wwn var inside + + var dat map[string]interface{} + if err := json.Unmarshal(byt, &dat); err != nil { + panic(err) + } + fakeClient.GetVolumeConfigReturns(dat, nil) + }) + AfterEach(func() { + Expect(fakeClient.GetVolumeCallCount()).To(Equal(1)) + Expect(fakeMounterFactory.GetMounterPerBackendCallCount()).To(Equal(1)) + Expect(fakeClient.GetVolumeConfigCallCount()).To(Equal(1)) + Expect(fakeMounter.UnmountCallCount()).To(Equal(0)) + Expect(fakeExec.LstatCallCount()).To(Equal(1)) + }) + + // Start with all the failures in this function + It("should fail because slink lstat error diff from not exist", func() { + fakeExec.LstatReturns(nil, errstrObj) + fakeExec.IsNotExistReturns(false) + unmountRequest := k8sresources.FlexVolumeUnmountRequest{MountPath: "/pod/pv1"} + + response := controller.Unmount(unmountRequest) + + Expect(fakeExec.IsNotExistCallCount()).To(Equal(1)) + Expect(response.Message).To(MatchRegexp(errstr)) + Expect(response.Status).To(Equal(ctl.FlexFailureStr)) + }) + It("should fail because its an real slink but cannot eval it", func() { + fakeExec.LstatReturns(nil, nil) + fakeExec.IsSlinkReturns(true) + fakeExec.EvalSymlinksReturns("", errstrObj) + + unmountRequest := k8sresources.FlexVolumeUnmountRequest{MountPath: "/pod/pv1"} + + response := controller.Unmount(unmountRequest) + + Expect(fakeExec.IsSlinkCallCount()).To(Equal(1)) + Expect(fakeExec.EvalSymlinksCallCount()).To(Equal(1)) + Expect(response.Message).To(MatchRegexp(errstr)) + Expect(response.Status).To(Equal(ctl.FlexFailureStr)) + }) + It("should fail because its an real slink but cannot eval it", func() { + fakeExec.LstatReturns(nil, nil) + fakeExec.IsSlinkReturns(true) + fakeExec.EvalSymlinksReturns("/fake/evalOfSlink", nil) + + unmountRequest := k8sresources.FlexVolumeUnmountRequest{MountPath: "/pod/pv1"} + + response := controller.Unmount(unmountRequest) + + Expect(fakeExec.IsSlinkCallCount()).To(Equal(1)) + Expect(fakeExec.EvalSymlinksCallCount()).To(Equal(1)) + Expect(response.Message).To(MatchRegexp(ctl.WrongSlinkErrorStr)) + Expect(response.Status).To(Equal(ctl.FlexFailureStr)) + }) + It("should fail because slink exist but its not slink", func() { + fakeExec.LstatReturns(nil, nil) + fakeExec.IsSlinkReturns(false) + + unmountRequest := k8sresources.FlexVolumeUnmountRequest{MountPath: "/pod/pv1"} + + response := controller.Unmount(unmountRequest) + + Expect(fakeExec.IsSlinkCallCount()).To(Equal(1)) + Expect(fakeExec.EvalSymlinksCallCount()).To(Equal(0)) + Expect(response.Message).To(MatchRegexp(ctl.K8sPVDirectoryIsNotSlinkErrorStr)) + Expect(response.Status).To(Equal(ctl.FlexFailureStr)) + }) + + }) + Context(".Unmount checkSlinkBeforeUmount succeed with slink exist - so check slink removal and mounter.Mount", func() { + var ( + errstrObj error + errstr string + wwn string + ) + BeforeEach(func() { + errstr = "fakerror" + errstrObj = fmt.Errorf(errstr) + fakeClient.GetVolumeReturns(resources.Volume{Name: "pv1", Backend: resources.SCBE, Mountpoint: "fake"}, nil) + wwn = "fake" + byt := []byte(`{"Wwn":"fake"}`) // TODO should use the wwn var inside + + var dat map[string]interface{} + if err := json.Unmarshal(byt, &dat); err != nil { + panic(err) + } + fakeClient.GetVolumeConfigReturns(dat, nil) + fakeExec.LstatReturns(nil, nil) + fakeExec.IsSlinkReturns(true) + }) + AfterEach(func() { + Expect(fakeClient.GetVolumeCallCount()).To(Equal(1)) + Expect(fakeMounterFactory.GetMounterPerBackendCallCount()).To(Equal(1)) + Expect(fakeClient.GetVolumeConfigCallCount()).To(Equal(1)) + Expect(fakeExec.LstatCallCount()).To(Equal(1)) + Expect(fakeExec.IsSlinkCallCount()).To(Equal(1)) + Expect(fakeExec.EvalSymlinksCallCount()).To(Equal(1)) + Expect(fakeMounter.UnmountCallCount()).To(Equal(1)) + }) + It("should fail unmount because mounter.Unmount failed", func() { + fakeExec.EvalSymlinksReturns("/ubiquity/"+wwn, nil) + fakeMounter.UnmountReturns(errstrObj) + fakeMounterFactory.GetMounterPerBackendReturns(fakeMounter, nil) + controller = ctl.NewControllerWithClient(testLogger, ubiquityConfig, fakeClient, fakeExec, fakeMounterFactory) + + unmountRequest := k8sresources.FlexVolumeUnmountRequest{MountPath: "/pod/pv1"} + + response := controller.Unmount(unmountRequest) + + Expect(response.Message).To(MatchRegexp(errstr)) + Expect(response.Status).To(Equal(ctl.FlexFailureStr)) + }) + It("should fail unmount because the removal of slink failed (reminder in this stage the slink exist so it fail due to a real issue of the rm)", func() { + fakeExec.EvalSymlinksReturns("/ubiquity/"+wwn, nil) + fakeExec.RemoveReturns(errstrObj) + + fakeMounter.UnmountReturns(nil) + fakeMounterFactory.GetMounterPerBackendReturns(fakeMounter, nil) + controller = ctl.NewControllerWithClient(testLogger, ubiquityConfig, fakeClient, fakeExec, fakeMounterFactory) + unmountRequest := k8sresources.FlexVolumeUnmountRequest{MountPath: "/pod/pv1"} + + response := controller.Unmount(unmountRequest) + + Expect(response.Message).To(MatchRegexp(errstr)) + Expect(response.Status).To(Equal(ctl.FlexFailureStr)) + }) + //TODO continue from here!!!!!!!!!!!! to add UT for slink not exist at all. and then continue the flow for after mounter.Unmount + + }) + Context(".Unmount check good path of doUnmount till hit the first error in doLegacyDetach", func() { + var ( + errstrObj error + errstr string + wwn string + ) + BeforeEach(func() { + errstr = "fakerror" + errstrObj = fmt.Errorf(errstr) + fakeClient.GetVolumeReturns(resources.Volume{Name: "pv1", Backend: resources.SCBE, Mountpoint: "fake"}, nil) + wwn = "fake" + byt := []byte(`{"Wwn":"fake"}`) // TODO should use the wwn var inside + + var dat map[string]interface{} + if err := json.Unmarshal(byt, &dat); err != nil { + panic(err) + } + fakeClient.GetVolumeConfigReturnsOnCall(0, dat, nil) + fakeClient.GetVolumeConfigReturnsOnCall(1, dat, errstrObj) // the first fail in doLegacyDetach + }) + AfterEach(func() { + fmt.Println("11111111111111111111") + Expect(fakeClient.GetVolumeCallCount()).To(Equal(1)) + Expect(fakeMounterFactory.GetMounterPerBackendCallCount()).To(Equal(1)) + Expect(fakeClient.GetVolumeConfigCallCount()).To(Equal(2)) // first in doUnmount and second is in the legacy + }) + It("should succeed doUnmount with slink exist(means doing mounter.Unmount) but fail during doLegacyDetach", func() { + fakeExec.EvalSymlinksReturns("/ubiquity/"+wwn, nil) + fakeMounter.UnmountReturns(nil) + fakeMounterFactory.GetMounterPerBackendReturns(fakeMounter, nil) + controller = ctl.NewControllerWithClient(testLogger, ubiquityConfig, fakeClient, fakeExec, fakeMounterFactory) + fakeExec.IsSlinkReturns(true) + fakeExec.LstatReturns(nil, nil) + + unmountRequest := k8sresources.FlexVolumeUnmountRequest{MountPath: "/pod/pv1"} + + response := controller.Unmount(unmountRequest) + + Expect(fakeExec.LstatCallCount()).To(Equal(1)) + Expect(fakeExec.EvalSymlinksCallCount()).To(Equal(1)) + Expect(fakeMounter.UnmountCallCount()).To(Equal(1)) + Expect(response.Message).To(MatchRegexp(errstr)) + Expect(response.Status).To(Equal(ctl.FlexFailureStr)) + }) + It("should succeed doUnmount because slink not exist (no need to run mounter.Unmount) but then lets fail it during doLegacyDetach", func() { + fakeExec.EvalSymlinksReturns("/ubiquity/"+wwn, nil) + fakeMounter.UnmountReturns(nil) + fakeMounterFactory.GetMounterPerBackendReturns(fakeMounter, nil) + controller = ctl.NewControllerWithClient(testLogger, ubiquityConfig, fakeClient, fakeExec, fakeMounterFactory) + fakeExec.IsSlinkReturns(true) + fakeExec.LstatReturns(nil, fmt.Errorf("error because file not exist")) // simulate idempotent with no slink exist + fakeExec.IsNotExistReturns(true) // simulate idempotent with no slink exist + unmountRequest := k8sresources.FlexVolumeUnmountRequest{MountPath: "/pod/pv1"} + + response := controller.Unmount(unmountRequest) + + Expect(response.Message).To(MatchRegexp(errstr)) + Expect(response.Status).To(Equal(ctl.FlexFailureStr)) + }) + // So now we actually finish all unit tests of Unmount before calling doLegacyDetach + // From now we need to start test the doLegacyDetach aspects. + }) + }) /* diff --git a/controller/errors.go b/controller/errors.go index 5dc706f7e..71d364660 100644 --- a/controller/errors.go +++ b/controller/errors.go @@ -77,3 +77,38 @@ func (e *k8sPVDirectoryIsNotDirNorSlinkError) Error() string { return fmt.Sprintf(K8sPVDirectoryIsNotDirNorSlinkErrorStr+" slink=[%s], fileInfo=[%#v]", e.slink, e.fileInfo) } + +const IdempotentUnmountSkipOnVolumeNotExistWarnigMsg = "Warning: Unmount operation requested to work on not exist volume. Assume its idempotent issue - so skip Unmount." + +const K8sPVDirectoryIsNotSlinkErrorStr = "k8s PV directory, k8s-mountpoint, is not slink." + +type k8sPVDirectoryIsNotSlinkError struct { + slink string + fileInfo os.FileInfo +} + +func (e *k8sPVDirectoryIsNotSlinkError) Error() string { + // The error string contains also the fileInfo for debug purpose, in order to identify for example what is the actual FileInfo.Mode(). + return fmt.Sprintf(K8sPVDirectoryIsNotSlinkErrorStr+" slink=[%s], fileInfo=[%#v]", + e.slink, e.fileInfo) +} + +const PvBackendNotSupportedErrorStr = "Backend type not supported." + +type PvBackendNotSupportedError struct { + Backend string +} + +func (e *PvBackendNotSupportedError) Error() string { + return fmt.Sprintf(PvBackendNotSupportedErrorStr+" backend=[%s]", e.Backend) +} + +const BackendNotImplementedGetRealMountpointErrorStr = "Backend do not support getting the real mountpoint from PV" + +type BackendNotImplementedGetRealMountpointError struct { + Backend string +} + +func (e *BackendNotImplementedGetRealMountpointError) Error() string { + return fmt.Sprintf(BackendNotImplementedGetRealMountpointErrorStr+" backend=[%s]", e.Backend) +} From a5f114e95a43464b069277e1f2394db10b715ab0 Mon Sep 17 00:00:00 2001 From: olgashtivelman <33713489+olgashtivelman@users.noreply.github.com> Date: Wed, 27 Jun 2018 16:59:21 +0300 Subject: [PATCH 11/40] Fix/ub 1325 change logger not to show pid and goroutine (#194) In this PR I wanted to update the new logging to the following state: in the ubiquity logger there we be shown the go routine id (and the pid will be removed from the log) : because the ubiquity server always runs in the same pid so no need to show it in the log since it does not give us any more information. in flex logger we will show the pid only (the go id routine will be removed) : since every flex request will always have the same go routine id there is not need to show both the request id and the go routine id. in provisioner log we will neither show the go routine id nor the pid of the process : since as for the flex logger each request will always have the same go routine id. and also like the ubiqity server the provisioner will always run with the same pid. --- cmd/flex/main/cli.go | 24 +++++++++++++----------- cmd/provisioner/main/main.go | 3 +-- controller/controller_suite_test.go | 2 +- utils/logger_utils.go | 21 +++++++++++++++++++++ volume/provision.go | 2 +- volume/provision_suite_test.go | 2 +- 6 files changed, 38 insertions(+), 16 deletions(-) create mode 100644 utils/logger_utils.go diff --git a/cmd/flex/main/cli.go b/cmd/flex/main/cli.go index ad843c6d4..64bfbc517 100644 --- a/cmd/flex/main/cli.go +++ b/cmd/flex/main/cli.go @@ -21,7 +21,6 @@ import ( "flag" "fmt" "os" - "path" "github.com/BurntSushi/toml" "github.com/IBM/ubiquity-k8s/controller" @@ -34,6 +33,7 @@ import ( "github.com/IBM/ubiquity/resources" "github.com/IBM/ubiquity/utils" "github.com/IBM/ubiquity/utils/logs" + k8sutils "github.com/IBM/ubiquity-k8s/utils" ) var configFile = flag.String( @@ -123,7 +123,7 @@ func (a *AttachCommand) Execute(args []string) error { } return printResponse(response) } - defer logs.InitFileLogger(logs.GetLogLevelFromString(config.LogLevel), path.Join(config.LogPath, k8sresources.UbiquityFlexLogFileName), config.LogRotateMaxSize)() + defer k8sutils.InitFlexLogger(config)() controller, err := createController(config) if err != nil { @@ -170,7 +170,7 @@ func (wfa *WaitForAttachCommand) Execute(args []string) error { } return printResponse(response) } - defer logs.InitFileLogger(logs.GetLogLevelFromString(config.LogLevel), path.Join(config.LogPath, k8sresources.UbiquityFlexLogFileName), config.LogRotateMaxSize)() + defer k8sutils.InitFlexLogger(config)() controller, err := createController(config) opts := make(map[string]string) err = json.Unmarshal([]byte(args[1]), &opts) @@ -210,7 +210,7 @@ func (d *IsAttachedCommand) Execute(args []string) error { } return printResponse(response) } - defer logs.InitFileLogger(logs.GetLogLevelFromString(config.LogLevel), path.Join(config.LogPath, k8sresources.UbiquityFlexLogFileName), config.LogRotateMaxSize)() + defer k8sutils.InitFlexLogger(config)() controller, err := createController(config) opts := make(map[string]string) err = json.Unmarshal([]byte(args[0]), &opts) @@ -261,7 +261,7 @@ func (d *DetachCommand) Execute(args []string) error { } return printResponse(response) } - defer logs.InitFileLogger(logs.GetLogLevelFromString(config.LogLevel), path.Join(config.LogPath, k8sresources.UbiquityFlexLogFileName), config.LogRotateMaxSize)() + defer k8sutils.InitFlexLogger(config)() controller, err := createController(config) if err != nil { @@ -297,7 +297,7 @@ func (d *MountDeviceCommand) Execute(args []string) error { } return printResponse(response) } - defer logs.InitFileLogger(logs.GetLogLevelFromString(config.LogLevel), path.Join(config.LogPath, k8sresources.UbiquityFlexLogFileName), config.LogRotateMaxSize)() + defer k8sutils.InitFlexLogger(config)() controller, err := createController(config) opts := make(map[string]string) err = json.Unmarshal([]byte(args[2]), &opts) @@ -337,7 +337,7 @@ func (d *UnmountDeviceCommand) Execute(args []string) error { } return printResponse(response) } - defer logs.InitFileLogger(logs.GetLogLevelFromString(config.LogLevel), path.Join(config.LogPath, k8sresources.UbiquityFlexLogFileName), config.LogRotateMaxSize)() + defer k8sutils.InitFlexLogger(config)() controller, err := createController(config) unmountDeviceRequest := k8sresources.FlexVolumeUnmountDeviceRequest{Name: args[0], Context: requestContext} @@ -421,7 +421,7 @@ func (m *MountCommand) Execute(args []string) error { return printResponse(response) } - defer logs.InitFileLogger(logs.GetLogLevelFromString(config.LogLevel), path.Join(config.LogPath, k8sresources.UbiquityFlexLogFileName), config.LogRotateMaxSize)() + defer k8sutils.InitFlexLogger(config)() controller, err := createController(config) if err != nil { @@ -458,7 +458,8 @@ func (u *UnmountCommand) Execute(args []string) error { } return printResponse(response) } - defer logs.InitFileLogger(logs.GetLogLevelFromString(config.LogLevel), path.Join(config.LogPath, k8sresources.UbiquityFlexLogFileName), config.LogRotateMaxSize)() + + defer k8sutils.InitFlexLogger(config)() controller, err := createController(config) if err != nil { @@ -486,7 +487,8 @@ func (i *TestUbiquityCommand) Execute(args []string) error { } return printResponse(response) } - defer logs.InitFileLogger(logs.GetLogLevelFromString(config.LogLevel), path.Join(config.LogPath, k8sresources.UbiquityFlexLogFileName), config.LogRotateMaxSize)() + + defer k8sutils.InitFlexLogger(config)() controller, err := createController(config) if err != nil { response := k8sresources.FlexVolumeResponse{ @@ -596,4 +598,4 @@ func printResponse(f k8sresources.FlexVolumeResponse) error { } fmt.Printf("%s", string(responseBytes[:])) return nil -} +} \ No newline at end of file diff --git a/cmd/provisioner/main/main.go b/cmd/provisioner/main/main.go index f6b7c1ba8..20a9f4ee3 100644 --- a/cmd/provisioner/main/main.go +++ b/cmd/provisioner/main/main.go @@ -24,7 +24,6 @@ import ( "github.com/IBM/ubiquity-k8s/volume" "github.com/IBM/ubiquity/remote" "github.com/IBM/ubiquity/utils" - "github.com/IBM/ubiquity/utils/logs" "github.com/kubernetes-incubator/external-storage/lib/controller" "k8s.io/apimachinery/pkg/util/wait" "k8s.io/client-go/kubernetes" @@ -51,7 +50,7 @@ func main() { panic(fmt.Errorf("Failed to setup log dir")) } - defer logs.InitStdoutLogger(logs.GetLogLevelFromString(ubiquityConfig.LogLevel))() + defer k8sutils.InitProvisionerLogger(ubiquityConfig)() logger := utils.SetupOldLogger(k8sresources.UbiquityProvisionerName) logger.Printf("Provisioner %s specified", provisioner) diff --git a/controller/controller_suite_test.go b/controller/controller_suite_test.go index 619b4eb64..67705208f 100644 --- a/controller/controller_suite_test.go +++ b/controller/controller_suite_test.go @@ -33,7 +33,7 @@ var logFile *os.File func TestController(t *testing.T) { RegisterFailHandler(Fail) - defer logs.InitStdoutLogger(logs.DEBUG)() + defer logs.InitStdoutLogger(logs.DEBUG, logs.LoggerParams{})() RunSpecs(t, "Controller Suite") } diff --git a/utils/logger_utils.go b/utils/logger_utils.go new file mode 100644 index 000000000..84b567300 --- /dev/null +++ b/utils/logger_utils.go @@ -0,0 +1,21 @@ +package utils + +import ( + "github.com/IBM/ubiquity/utils/logs" + k8sresources "github.com/IBM/ubiquity-k8s/resources" + "github.com/IBM/ubiquity/resources" + "path" +) + +func InitFlexLogger(config resources.UbiquityPluginConfig) func(){ + var logger_params = logs.LoggerParams{ShowGoid: false, ShowPid : true} + deferFunction := logs.InitFileLogger(logs.GetLogLevelFromString(config.LogLevel), path.Join(config.LogPath, k8sresources.UbiquityFlexLogFileName), config.LogRotateMaxSize, logger_params) + return deferFunction +} + +func InitProvisionerLogger(ubiquityConfig resources.UbiquityPluginConfig) func(){ + deferFunction := logs.InitStdoutLogger(logs.GetLogLevelFromString(ubiquityConfig.LogLevel), logs.LoggerParams{ShowGoid: false, ShowPid : false}) + return deferFunction +} + + diff --git a/volume/provision.go b/volume/provision.go index ff275c998..20b42580b 100644 --- a/volume/provision.go +++ b/volume/provision.go @@ -181,7 +181,7 @@ func (p *flexProvisioner) Provision(options controller.VolumeOptions) (*v1.Persi // PV. func (p *flexProvisioner) Delete(volume *v1.PersistentVolume) error { requestContext := logs.GetNewRequestContext() - go_id := logs.GetGoID() + go_id := logs.GetGoID() logs.GoIdToRequestIdMap.Store(go_id, requestContext) defer logs.GetDeleteFromMapFunc(go_id) defer p.logger.Trace(logs.DEBUG, logs.Args{{"volume name", volume.Name}})() diff --git a/volume/provision_suite_test.go b/volume/provision_suite_test.go index f70ded196..1ca7c1f32 100644 --- a/volume/provision_suite_test.go +++ b/volume/provision_suite_test.go @@ -33,7 +33,7 @@ var logFile *os.File func TestController(t *testing.T) { RegisterFailHandler(Fail) - defer logs.InitStdoutLogger(logs.DEBUG)() + defer logs.InitStdoutLogger(logs.DEBUG, logs.LoggerParams{})() RunSpecs(t, "Provisioner Suite") } From fad3eca3f5ad8926f10057e78a6a9a361e067e6c Mon Sep 17 00:00:00 2001 From: Shay Berman Date: Mon, 2 Jul 2018 08:47:23 +0300 Subject: [PATCH 12/40] Remove old ubiquity linux service, config files and few old deployment files. --- Dockerfile.Flex | 2 +- .../ubiquity-configmap/ubiquity-k8s-flex.conf | 16 -------- .../ubiquity_provisioner_deployment.yml | 38 ------------------- scripts/setup | 10 ----- .../k8s_deployments => scripts}/setup_flex.sh | 0 scripts/setup_provisioner | 21 ---------- scripts/ubiquity-k8s-provisioner.env | 20 ---------- scripts/ubiquity-k8s-provisioner.service | 17 --------- ubiquity-k8s-provisioner.conf | 13 ------- 9 files changed, 1 insertion(+), 136 deletions(-) delete mode 100644 deploy/k8s_deployments/ubiquity-configmap/ubiquity-k8s-flex.conf delete mode 100644 deploy/k8s_deployments/ubiquity_provisioner_deployment.yml delete mode 100755 scripts/setup rename {deploy/k8s_deployments => scripts}/setup_flex.sh (100%) delete mode 100755 scripts/setup_provisioner delete mode 100644 scripts/ubiquity-k8s-provisioner.env delete mode 100644 scripts/ubiquity-k8s-provisioner.service delete mode 100644 ubiquity-k8s-provisioner.conf diff --git a/Dockerfile.Flex b/Dockerfile.Flex index 46af584f3..0605f2318 100644 --- a/Dockerfile.Flex +++ b/Dockerfile.Flex @@ -11,6 +11,6 @@ RUN apk --no-cache add ca-certificates=20171114-r0 ENV UBIQUITY_PLUGIN_VERIFY_CA=/var/lib/ubiquity/ssl/public/ubiquity-trusted-ca.crt WORKDIR /root/ COPY --from=0 /go/src/github.com/IBM/ubiquity-k8s/ubiquity-k8s-flex . -COPY --from=0 /go/src/github.com/IBM/ubiquity-k8s/deploy/k8s_deployments/setup_flex.sh . +COPY --from=0 /go/src/github.com/IBM/ubiquity-k8s/scripts/setup_flex.sh . COPY --from=0 /go/src/github.com/IBM/ubiquity-k8s/LICENSE . COPY --from=0 /go/src/github.com/IBM/ubiquity-k8s/scripts/notices_file_for_ibm_storage_enabler_for_containers ./NOTICES diff --git a/deploy/k8s_deployments/ubiquity-configmap/ubiquity-k8s-flex.conf b/deploy/k8s_deployments/ubiquity-configmap/ubiquity-k8s-flex.conf deleted file mode 100644 index 928a52590..000000000 --- a/deploy/k8s_deployments/ubiquity-configmap/ubiquity-k8s-flex.conf +++ /dev/null @@ -1,16 +0,0 @@ -# NOTE : This script is obsolete - go to scripts/installer-for-ibm-storage-enabler-for-containers - -logPath = "/var/tmp/ubiquity" -backends = ["spectrum-scale"] -logLevel = "info" # debug / info / error - -[UbiquityServer] -address = "127.0.0.1" -port = 9999 - -[SpectrumNfsRemoteConfig] -ClientConfig = "192.168.1.0/24(Access_Type=RW,Protocols=3:4,Transports=TCP:UDP)" - -[CredentialInfo] -username = "USER" -password = "PASSWORD" \ No newline at end of file diff --git a/deploy/k8s_deployments/ubiquity_provisioner_deployment.yml b/deploy/k8s_deployments/ubiquity_provisioner_deployment.yml deleted file mode 100644 index 2ede73228..000000000 --- a/deploy/k8s_deployments/ubiquity_provisioner_deployment.yml +++ /dev/null @@ -1,38 +0,0 @@ ---- -apiVersion: "extensions/v1beta1" -kind: Deployment -metadata: - name: ubiquity-provisioner -spec: - replicas: 1 - template: - metadata: - labels: - app: ubiquity-provisioner - spec: - containers: - - name: ubiquity-provisioner - image: IBM-ubiquity-provisioner-IMAGE # place holder - imagePullPolicy: Always - env: - - name: KUBECONFIG - value: "/tmp/k8sconfig/config" - - name: LOG_PATH # provisioner log file directory - value: "/tmp" - - name: BACKENDS # used backends "spectrum-scale,spectrum-scale-nfs,scbe" - value: "spectrum-scale,scbe" # - - name: LOG_LEVEL # debug / info / error - value: "info" - - name: UBIQUITY_ADDRESS # Address of ubiquity service - value: "10.99.234.242" - - name: UBIQUITY_PORT # Port of ubiquity service - value: "9999" - - name: SCBE_SKIP_RESCAN_ISCSI # Wheter or not to skip rescan iscsi - value: "true" - volumeMounts: - - name: k8s-config - mountPath: /tmp/k8sconfig - volumes: - - name: k8s-config - configMap: #configmap containing kubernetes config file - name: k8s-config \ No newline at end of file diff --git a/scripts/setup b/scripts/setup deleted file mode 100755 index 16a958280..000000000 --- a/scripts/setup +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/bash - -set -e - -scripts=$(dirname $0) -flexdir=/usr/libexec/kubernetes/kubelet-plugins/volume/exec/ibm~ubiquity-k8s-flex -mkdir -p $flexdir - -cp $scripts/../bin/ubiquity-k8s-flex $flexdir/ubiquity-k8s-flex -cp $scripts/../ubiquity-k8s-flex.conf $flexdir/ubiquity-k8s-flex.conf diff --git a/deploy/k8s_deployments/setup_flex.sh b/scripts/setup_flex.sh similarity index 100% rename from deploy/k8s_deployments/setup_flex.sh rename to scripts/setup_flex.sh diff --git a/scripts/setup_provisioner b/scripts/setup_provisioner deleted file mode 100755 index ded0360d6..000000000 --- a/scripts/setup_provisioner +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/bash - -set -e -scripts=$(dirname $0) - -mkdir -p /etc/ubiquity - -cp $scripts/../bin/ubiquity-k8s-provisioner /usr/bin/ubiquity-k8s-provisioner - -cp $scripts/../ubiquity-k8s-provisioner.conf \ -/etc/ubiquity/ubiquity-k8s-provisioner.conf - -cp $scripts/ubiquity-k8s-provisioner.env /etc/ubiquity/ubiquity-k8s-provisioner.env - -dist=`lsb_release -a 2>/dev/null |grep "Distributor ID" |cut -d: -f2 |xargs` -if [ "$dist" == "Ubuntu" ]; then - cp $scripts/ubiquity-k8s-provisioner.service /lib/systemd/system/ -else - cp $scripts/ubiquity-k8s-provisioner.service /usr/lib/systemd/system/ -fi -systemctl enable ubiquity-k8s-provisioner diff --git a/scripts/ubiquity-k8s-provisioner.env b/scripts/ubiquity-k8s-provisioner.env deleted file mode 100644 index acae637d9..000000000 --- a/scripts/ubiquity-k8s-provisioner.env +++ /dev/null @@ -1,20 +0,0 @@ -### -# Ubiquity K8s dynamic provisioner options - -# NOTE : This script is obsolete because ubiquity is been installed as docker image. - -# Config file of ubiquity K8s provisioner -UBIQUITY_CLIENT_CONFIG="--config /etc/ubiquity/ubiquity-client-k8s.conf" - -# K8 kubeconfig file - -KUBE_CONFIG="--kubeconfig /tmp/kube_config" - -# provisioner name - -PROVISIONER_NAME="--provisioner ubiquity/flex" - -# Add your own arguments - -PROVISIONER_ARGS= - diff --git a/scripts/ubiquity-k8s-provisioner.service b/scripts/ubiquity-k8s-provisioner.service deleted file mode 100644 index 3def6b1a6..000000000 --- a/scripts/ubiquity-k8s-provisioner.service +++ /dev/null @@ -1,17 +0,0 @@ - -[Unit] -Description=ubiquity k8s dynamic provisioner -Documentation=https://github.com/IBM/ubiquity-k8s -After=network.target - -[Service] -Type=simple -ExecStart=/usr/bin/ubiquity-k8s-provisioner \ - --config /etc/ubiquity/ubiquity-k8s-provisioner.conf \ - --provisioner ubiquity/flex \ - --retries 3 - -Restart=on-abort - -[Install] -WantedBy=multi-user.target diff --git a/ubiquity-k8s-provisioner.conf b/ubiquity-k8s-provisioner.conf deleted file mode 100644 index 4b54bf53d..000000000 --- a/ubiquity-k8s-provisioner.conf +++ /dev/null @@ -1,13 +0,0 @@ -# NOTE : This script is obsolete because ubiquity is been installed as docker image. - -logPath = "/var/tmp/ubiquity" -backends = ["spectrum-scale"] -logLevel = "info" # debug / info / error - -[UbiquityServer] -address = "127.0.0.1" -port = 9999 - -[CredentialInfo] -username = "USER" -password = "PASSWORD" From 6844c539f5cb60001385853fbf0093ea874ba6a5 Mon Sep 17 00:00:00 2001 From: Shay Berman Date: Mon, 2 Jul 2018 09:20:21 +0300 Subject: [PATCH 13/40] Move the acceptance test scripts to a dedicated directory scripts/acceptance_tests --- .../acceptance_utils.sh | 0 .../cleanup_acceptance.sh | 6 +-- .../acceptance_tests/deploy}/deployment.yml | 0 .../acceptance_tests/deploy}/pod.yml | 0 .../acceptance_tests/deploy}/pvc_fileset.yml | 0 .../deploy}/pvc_lightweight.yml | 0 .../deploy}/readme_yml/pod1.yml | 0 .../deploy}/readme_yml/pvc1.yml | 0 .../deploy}/readme_yml/storage_class_gold.yml | 0 .../deploy}/scbe_volume_pvc.yml | 0 .../deploy}/scbe_volume_pvc_template.yml | 0 .../deploy}/scbe_volume_storage_class.yml | 0 .../scbe_volume_storage_class_template.yml | 0 .../deploy}/scbe_volume_with_pod.yml | 0 .../deploy}/scbe_volume_with_pod_template.yml | 0 ...be_volume_with_pod_with_2vols_template.yml | 0 .../deploy}/storage_class_fileset.yml | 0 .../deploy}/storage_class_fileset_nfs.yml | 0 .../deploy}/storage_class_lightweight.yml | 0 .../{ => acceptance_tests}/flex_smoke_test.sh | 0 .../{ => acceptance_tests}/run_acceptance.sh | 12 ++--- ...n_acceptance_ibm_block_storage_via_scbe.sh | 48 +++++++++---------- scripts/clean | 5 -- 23 files changed, 33 insertions(+), 38 deletions(-) rename scripts/{ => acceptance_tests}/acceptance_utils.sh (100%) rename scripts/{ => acceptance_tests}/cleanup_acceptance.sh (65%) rename {deploy => scripts/acceptance_tests/deploy}/deployment.yml (100%) rename {deploy => scripts/acceptance_tests/deploy}/pod.yml (100%) rename {deploy => scripts/acceptance_tests/deploy}/pvc_fileset.yml (100%) rename {deploy => scripts/acceptance_tests/deploy}/pvc_lightweight.yml (100%) rename {deploy => scripts/acceptance_tests/deploy}/readme_yml/pod1.yml (100%) rename {deploy => scripts/acceptance_tests/deploy}/readme_yml/pvc1.yml (100%) rename {deploy => scripts/acceptance_tests/deploy}/readme_yml/storage_class_gold.yml (100%) rename {deploy => scripts/acceptance_tests/deploy}/scbe_volume_pvc.yml (100%) rename {deploy => scripts/acceptance_tests/deploy}/scbe_volume_pvc_template.yml (100%) rename {deploy => scripts/acceptance_tests/deploy}/scbe_volume_storage_class.yml (100%) rename {deploy => scripts/acceptance_tests/deploy}/scbe_volume_storage_class_template.yml (100%) rename {deploy => scripts/acceptance_tests/deploy}/scbe_volume_with_pod.yml (100%) rename {deploy => scripts/acceptance_tests/deploy}/scbe_volume_with_pod_template.yml (100%) rename {deploy => scripts/acceptance_tests/deploy}/scbe_volume_with_pod_with_2vols_template.yml (100%) rename {deploy => scripts/acceptance_tests/deploy}/storage_class_fileset.yml (100%) rename {deploy => scripts/acceptance_tests/deploy}/storage_class_fileset_nfs.yml (100%) rename {deploy => scripts/acceptance_tests/deploy}/storage_class_lightweight.yml (100%) rename scripts/{ => acceptance_tests}/flex_smoke_test.sh (100%) rename scripts/{ => acceptance_tests}/run_acceptance.sh (71%) rename scripts/{ => acceptance_tests}/run_acceptance_ibm_block_storage_via_scbe.sh (94%) delete mode 100755 scripts/clean diff --git a/scripts/acceptance_utils.sh b/scripts/acceptance_tests/acceptance_utils.sh similarity index 100% rename from scripts/acceptance_utils.sh rename to scripts/acceptance_tests/acceptance_utils.sh diff --git a/scripts/cleanup_acceptance.sh b/scripts/acceptance_tests/cleanup_acceptance.sh similarity index 65% rename from scripts/cleanup_acceptance.sh rename to scripts/acceptance_tests/cleanup_acceptance.sh index cea9efd17..b5ca94d2f 100755 --- a/scripts/cleanup_acceptance.sh +++ b/scripts/acceptance_tests/cleanup_acceptance.sh @@ -8,10 +8,10 @@ scripts=$(dirname $0) echo "Cleaning test environment" echo "Deleting Pod" -kubectl delete -f $scripts/../deploy/pod.yml +kubectl delete -f $scripts/deploy/pod.yml echo "Deleting Persistent Volume Claim" -kubectl delete -f $scripts/../deploy/pvc_fileset.yml +kubectl delete -f $scripts/deploy/pvc_fileset.yml echo "Listing PVC" kubectl get pvc @@ -20,7 +20,7 @@ echo "Listing PV" kubectl get pv echo "Deleting Storage Class" -kubectl delete -f $scripts/../deploy/storage_class_fileset.yml +kubectl delete -f $scripts/deploy/storage_class_fileset.yml echo "Listing Storage Classes" kubectl get storageclass \ No newline at end of file diff --git a/deploy/deployment.yml b/scripts/acceptance_tests/deploy/deployment.yml similarity index 100% rename from deploy/deployment.yml rename to scripts/acceptance_tests/deploy/deployment.yml diff --git a/deploy/pod.yml b/scripts/acceptance_tests/deploy/pod.yml similarity index 100% rename from deploy/pod.yml rename to scripts/acceptance_tests/deploy/pod.yml diff --git a/deploy/pvc_fileset.yml b/scripts/acceptance_tests/deploy/pvc_fileset.yml similarity index 100% rename from deploy/pvc_fileset.yml rename to scripts/acceptance_tests/deploy/pvc_fileset.yml diff --git a/deploy/pvc_lightweight.yml b/scripts/acceptance_tests/deploy/pvc_lightweight.yml similarity index 100% rename from deploy/pvc_lightweight.yml rename to scripts/acceptance_tests/deploy/pvc_lightweight.yml diff --git a/deploy/readme_yml/pod1.yml b/scripts/acceptance_tests/deploy/readme_yml/pod1.yml similarity index 100% rename from deploy/readme_yml/pod1.yml rename to scripts/acceptance_tests/deploy/readme_yml/pod1.yml diff --git a/deploy/readme_yml/pvc1.yml b/scripts/acceptance_tests/deploy/readme_yml/pvc1.yml similarity index 100% rename from deploy/readme_yml/pvc1.yml rename to scripts/acceptance_tests/deploy/readme_yml/pvc1.yml diff --git a/deploy/readme_yml/storage_class_gold.yml b/scripts/acceptance_tests/deploy/readme_yml/storage_class_gold.yml similarity index 100% rename from deploy/readme_yml/storage_class_gold.yml rename to scripts/acceptance_tests/deploy/readme_yml/storage_class_gold.yml diff --git a/deploy/scbe_volume_pvc.yml b/scripts/acceptance_tests/deploy/scbe_volume_pvc.yml similarity index 100% rename from deploy/scbe_volume_pvc.yml rename to scripts/acceptance_tests/deploy/scbe_volume_pvc.yml diff --git a/deploy/scbe_volume_pvc_template.yml b/scripts/acceptance_tests/deploy/scbe_volume_pvc_template.yml similarity index 100% rename from deploy/scbe_volume_pvc_template.yml rename to scripts/acceptance_tests/deploy/scbe_volume_pvc_template.yml diff --git a/deploy/scbe_volume_storage_class.yml b/scripts/acceptance_tests/deploy/scbe_volume_storage_class.yml similarity index 100% rename from deploy/scbe_volume_storage_class.yml rename to scripts/acceptance_tests/deploy/scbe_volume_storage_class.yml diff --git a/deploy/scbe_volume_storage_class_template.yml b/scripts/acceptance_tests/deploy/scbe_volume_storage_class_template.yml similarity index 100% rename from deploy/scbe_volume_storage_class_template.yml rename to scripts/acceptance_tests/deploy/scbe_volume_storage_class_template.yml diff --git a/deploy/scbe_volume_with_pod.yml b/scripts/acceptance_tests/deploy/scbe_volume_with_pod.yml similarity index 100% rename from deploy/scbe_volume_with_pod.yml rename to scripts/acceptance_tests/deploy/scbe_volume_with_pod.yml diff --git a/deploy/scbe_volume_with_pod_template.yml b/scripts/acceptance_tests/deploy/scbe_volume_with_pod_template.yml similarity index 100% rename from deploy/scbe_volume_with_pod_template.yml rename to scripts/acceptance_tests/deploy/scbe_volume_with_pod_template.yml diff --git a/deploy/scbe_volume_with_pod_with_2vols_template.yml b/scripts/acceptance_tests/deploy/scbe_volume_with_pod_with_2vols_template.yml similarity index 100% rename from deploy/scbe_volume_with_pod_with_2vols_template.yml rename to scripts/acceptance_tests/deploy/scbe_volume_with_pod_with_2vols_template.yml diff --git a/deploy/storage_class_fileset.yml b/scripts/acceptance_tests/deploy/storage_class_fileset.yml similarity index 100% rename from deploy/storage_class_fileset.yml rename to scripts/acceptance_tests/deploy/storage_class_fileset.yml diff --git a/deploy/storage_class_fileset_nfs.yml b/scripts/acceptance_tests/deploy/storage_class_fileset_nfs.yml similarity index 100% rename from deploy/storage_class_fileset_nfs.yml rename to scripts/acceptance_tests/deploy/storage_class_fileset_nfs.yml diff --git a/deploy/storage_class_lightweight.yml b/scripts/acceptance_tests/deploy/storage_class_lightweight.yml similarity index 100% rename from deploy/storage_class_lightweight.yml rename to scripts/acceptance_tests/deploy/storage_class_lightweight.yml diff --git a/scripts/flex_smoke_test.sh b/scripts/acceptance_tests/flex_smoke_test.sh similarity index 100% rename from scripts/flex_smoke_test.sh rename to scripts/acceptance_tests/flex_smoke_test.sh diff --git a/scripts/run_acceptance.sh b/scripts/acceptance_tests/run_acceptance.sh similarity index 71% rename from scripts/run_acceptance.sh rename to scripts/acceptance_tests/run_acceptance.sh index 4995ca2db..309fe3d0f 100755 --- a/scripts/run_acceptance.sh +++ b/scripts/acceptance_tests/run_acceptance.sh @@ -5,14 +5,14 @@ set -e scripts=$(dirname $0) echo "Creating Storage class...." -kubectl create -f $scripts/../deploy/storage_class_fileset.yml +kubectl create -f $scripts/deploy/storage_class_fileset.yml echo "Listing Storage classes" kubectl get storageclass echo "Creating Persistent Volume Claim..." -kubectl create -f $scripts/../deploy/pvc_fileset.yml +kubectl create -f $scripts/deploy/pvc_fileset.yml echo "Listing Persistent Volume Claim..." @@ -24,7 +24,7 @@ kubectl get pv echo "Creating Test Pod" -kubectl create -f $scripts/../deploy/pod.yml +kubectl create -f $scripts/deploy/pod.yml sleep 10 echo "Listing pods" @@ -40,10 +40,10 @@ kubectl exec write-pod-test -c write-pod ls /mnt echo "Cleaning test environment" echo "Deleting Pod" -kubectl delete -f $scripts/../deploy/pod.yml +kubectl delete -f $scripts/deploy/pod.yml echo "Deleting Persistent Volume Claim" -kubectl delete -f $scripts/../deploy/pvc_fileset.yml +kubectl delete -f $scripts/deploy/pvc_fileset.yml echo "Listing PVC" kubectl get pvc @@ -52,7 +52,7 @@ echo "Listing PV" kubectl get pv echo "Deleting Storage Class" -kubectl delete -f $scripts/../deploy/storage_class_fileset.yml +kubectl delete -f $scripts/deploy/storage_class_fileset.yml echo "Listing Storage Classes" kubectl get storageclass diff --git a/scripts/run_acceptance_ibm_block_storage_via_scbe.sh b/scripts/acceptance_tests/run_acceptance_ibm_block_storage_via_scbe.sh similarity index 94% rename from scripts/run_acceptance_ibm_block_storage_via_scbe.sh rename to scripts/acceptance_tests/run_acceptance_ibm_block_storage_via_scbe.sh index ffa8099b7..36a1c1dd6 100755 --- a/scripts/run_acceptance_ibm_block_storage_via_scbe.sh +++ b/scripts/acceptance_tests/run_acceptance_ibm_block_storage_via_scbe.sh @@ -59,7 +59,7 @@ function basic_tests_on_one_node() echo "########################### [basic POD test with PVC] ###############" find_multipath_faulty echo "####### ---> ${S}. Creating Storage class for ${profile} service" - yml_sc_profile=$scripts/../deploy/scbe_volume_storage_class_$profile.yml + yml_sc_profile=$scripts/deploy/scbe_volume_storage_class_$profile.yml cp -f ${yml_sc_tmplemt} ${yml_sc_profile} fstype=ext4 sed -i -e "s/PROFILE/$profile/g" -e "s/SCNAME/$profile/g" -e "s/FSTYPE/$fstype/g" ${yml_sc_profile} @@ -73,7 +73,7 @@ function basic_tests_on_one_node() kubectl get storageclass $profile echo "####### ---> ${S}. Create PVC (volume) on SCBE ${profile} service (which is on IBM FlashSystem A9000R)" - yml_pvc=$scripts/../deploy/scbe_volume_pvc_${PVCName}.yml + yml_pvc=$scripts/deploy/scbe_volume_pvc_${PVCName}.yml cp -f ${yml_pvc_template} ${yml_pvc} sed -i -e "s/PVCNAME/$PVCName/g" -e "s/SIZE/5Gi/g" -e "s/SCNAME/$profile/g" ${yml_pvc} cat ${yml_pvc} @@ -97,7 +97,7 @@ function basic_tests_on_one_node() stepinc echo "####### ---> ${S}. Run POD [$PODName] with container ${CName} with the new volume" - yml_pod1=$scripts/../deploy/scbe_volume_with_pod1.yml + yml_pod1=$scripts/deploy/scbe_volume_with_pod1.yml cp -f ${yml_pod_template} ${yml_pod1} sed -i -e "s/PODNAME/$PODName/g" -e "s/CONNAME/$CName/g" -e "s/VOLNAME/$volPODname/g" -e "s|MOUNTPATH|/data|g" -e "s/PVCNAME/$PVCName/g" -e "s/NODESELECTOR/${node1}/g" ${yml_pod1} cat $yml_pod1 @@ -192,20 +192,20 @@ function basic_tests_on_one_node_sc_pvc_pod_all_in_one() echo "########################### [All in one suite] ###############" find_multipath_faulty echo "####### ---> ${S}. Prepare all in one yaml with SC, PVC, POD yml" - yml_sc_profile=$scripts/../deploy/scbe_volume_storage_class_$profile.yml + yml_sc_profile=$scripts/deploy/scbe_volume_storage_class_$profile.yml cp -f ${yml_sc_tmplemt} ${yml_sc_profile} fstype=ext4 sed -i -e "s/PROFILE/$profile/g" -e "s/SCNAME/$profile/g" -e "s/FSTYPE/$fstype/g" ${yml_sc_profile} - yml_pvc=$scripts/../deploy/scbe_volume_pvc_${PVCName}.yml + yml_pvc=$scripts/deploy/scbe_volume_pvc_${PVCName}.yml cp -f ${yml_pvc_template} ${yml_pvc} sed -i -e "s/PVCNAME/$PVCName/g" -e "s/SIZE/5Gi/g" -e "s/SCNAME/$profile/g" ${yml_pvc} - yml_pod1=$scripts/../deploy/scbe_volume_with_pod1.yml + yml_pod1=$scripts/deploy/scbe_volume_with_pod1.yml cp -f ${yml_pod_template} ${yml_pod1} sed -i -e "s/PODNAME/$PODName/g" -e "s/CONNAME/$CName/g" -e "s/VOLNAME/$volPODname/g" -e "s|MOUNTPATH|/data|g" -e "s/PVCNAME/$PVCName/g" -e "s/NODESELECTOR/${node1}/g" ${yml_pod1} - ymk_sc_and_pvc_and_pod1=$scripts/../deploy/scbe_volume_with_sc_pvc_and_pod1.yml + ymk_sc_and_pvc_and_pod1=$scripts/deploy/scbe_volume_with_sc_pvc_and_pod1.yml cat ${yml_sc_profile} > ${ymk_sc_and_pvc_and_pod1} add_yaml_delimiter ${ymk_sc_and_pvc_and_pod1} cat ${yml_pvc} >> ${ymk_sc_and_pvc_and_pod1} @@ -249,23 +249,23 @@ function basic_test_POD_with_2_volumes() echo "########################### [Run 2 vols in the same POD-container] ###############" find_multipath_faulty echo "####### ---> ${S}. Prepare yml with all the definition" - yml_sc_profile=$scripts/../deploy/scbe_volume_storage_class_$profile.yml + yml_sc_profile=$scripts/deploy/scbe_volume_storage_class_$profile.yml cp -f ${yml_sc_tmplemt} ${yml_sc_profile} fstype=ext4 sed -i -e "s/PROFILE/$profile/g" -e "s/SCNAME/$profile/g" -e "s/FSTYPE/$fstype/g" ${yml_sc_profile} - yml_pvc1=$scripts/../deploy/scbe_volume_pvc_${PVCName}1.yml + yml_pvc1=$scripts/deploy/scbe_volume_pvc_${PVCName}1.yml cp -f ${yml_pvc_template} ${yml_pvc1} sed -i -e "s/PVCNAME/${PVCName}1/g" -e "s/SIZE/1Gi/g" -e "s/SCNAME/$profile/g" ${yml_pvc1} - yml_pvc2=$scripts/../deploy/scbe_volume_pvc_${PVCName}2.yml + yml_pvc2=$scripts/deploy/scbe_volume_pvc_${PVCName}2.yml cp -f ${yml_pvc_template} ${yml_pvc2} sed -i -e "s/PVCNAME/${PVCName}2/g" -e "s/SIZE/1Gi/g" -e "s/SCNAME/$profile/g" ${yml_pvc2} - yml_pod2=$scripts/../deploy/scbe_volume_with_pod2.yml + yml_pod2=$scripts/deploy/scbe_volume_with_pod2.yml cp -f ${yml_two_vols_pod_template} ${yml_pod2} sed -i -e "s/PODNAME/$PODName/g" -e "s/CONNAME/$CName/g" -e "s/VOLNAME1/${volPODname}1/g" -e "s|MOUNTPATH1|/data1|g" -e "s/PVCNAME1/${PVCName}1/g" -e "s/VOLNAME2/${volPODname}2/g" -e "s|MOUNTPATH2|/data2|g" -e "s/PVCNAME2/${PVCName}2/g" -e "s/NODESELECTOR/${node1}/g" ${yml_pod2} - my_yml=$scripts/../deploy/scbe_volume_with_sc_2pvc_and_pod.yml + my_yml=$scripts/deploy/scbe_volume_with_sc_2pvc_and_pod.yml cat ${yml_sc_profile} > ${my_yml} add_yaml_delimiter ${my_yml} cat ${yml_pvc1} >> ${my_yml} @@ -329,23 +329,23 @@ function fstype_basic_check() find_multipath_faulty echo "####### ---> ${S}. Prepare yml with all the definition" - my_yml=$scripts/../deploy/scbe_volume_with_2sc_2pvc_and_pod.yml + my_yml=$scripts/deploy/scbe_volume_with_2sc_2pvc_and_pod.yml cat /dev/null > ${my_yml} for fstype in ${FS_SUPPORTED}; do echo "Generate yml for SC and PVC and POD according to the $fstype" - yml_sc_profile=$scripts/../deploy/scbe_volume_storage_class_${profile}_${fstype}.yml + yml_sc_profile=$scripts/deploy/scbe_volume_storage_class_${profile}_${fstype}.yml cp -f ${yml_sc_tmplemt} ${yml_sc_profile} sed -i -e "s/PROFILE/$profile/g" -e "s/SCNAME/${profile}-${fstype}/g" -e "s/FSTYPE/$fstype/g" ${yml_sc_profile} add_yaml_delimiter ${yml_sc_profile} cat ${yml_sc_profile} >> ${my_yml} - yml_pvc1=$scripts/../deploy/scbe_volume_pvc_${PVCName}_${fstype}.yml + yml_pvc1=$scripts/deploy/scbe_volume_pvc_${PVCName}_${fstype}.yml cp -f ${yml_pvc_template} ${yml_pvc1} sed -i -e "s/PVCNAME/${PVCName}-${fstype}/g" -e "s/SIZE/1Gi/g" -e "s/SCNAME/${profile}-${fstype}/g" ${yml_pvc1} add_yaml_delimiter ${yml_pvc1} cat ${yml_pvc1} >> ${my_yml} - yml_pod1=$scripts/../deploy/scbe_volume_with_pod_with_pvc_for_each_fstype.yml + yml_pod1=$scripts/deploy/scbe_volume_with_pod_with_pvc_for_each_fstype.yml cp -f ${yml_pod_template} ${yml_pod1} sed -i -e "s/PODNAME/${PODName}-${fstype}/g" -e "s/CONNAME/${CName}-${fstype}/g" -e "s/VOLNAME/${volPODname}-${fstype}/g" -e "s|MOUNTPATH|/data-${fstype}|g" -e "s/PVCNAME/$PVCName-${fstype}/g" -e "s/NODESELECTOR/${node1}/g" ${yml_pod1} add_yaml_delimiter ${yml_pod1} @@ -422,7 +422,7 @@ function tests_with_second_node() echo "####### ---> ${S} Steps on NODE1 $node1" echo "## ---> ${S}.1 Creating Storage class for ${profile} service" - yml_sc_profile=$scripts/../deploy/scbe_volume_storage_class_$profile.yml + yml_sc_profile=$scripts/deploy/scbe_volume_storage_class_$profile.yml cp -f ${yml_sc_tmplemt} ${yml_sc_profile} fstype=ext4 sed -i -e "s/PROFILE/$profile/g" -e "s/SCNAME/$profile/g" -e "s/FSTYPE/$fstype/g" ${yml_sc_profile} @@ -431,7 +431,7 @@ function tests_with_second_node() kubectl get storageclass $profile echo "## --> ${S}.2 Create PVC (volume) on SCBE ${profile} service (which is on IBM FlashSystem A9000R)" - yml_pvc=$scripts/../deploy/scbe_volume_pvc_${PVCName}.yml + yml_pvc=$scripts/deploy/scbe_volume_pvc_${PVCName}.yml cp -f ${yml_pvc_template} ${yml_pvc} sed -i -e "s/PVCNAME/$PVCName/g" -e "s/SIZE/5Gi/g" -e "s/SCNAME/$profile/g" ${yml_pvc} cat ${yml_pvc} @@ -445,7 +445,7 @@ function tests_with_second_node() wwn=`kubectl get pv --no-headers -o custom-columns=wwn:spec.flexVolume.options.Wwn $pvname` echo "## ---> ${S}.4. Run POD [$PODName] with container ${CName} with the new volume" - yml_pod1=$scripts/../deploy/scbe_volume_with_pod1.yml + yml_pod1=$scripts/deploy/scbe_volume_with_pod1.yml cp -f ${yml_pod_template} ${yml_pod1} sed -i -e "s/PODNAME/$PODName/g" -e "s/CONNAME/$CName/g" -e "s/VOLNAME/$volPODname/g" -e "s|MOUNTPATH|/data|g" -e "s/PVCNAME/$PVCName/g" -e "s/NODESELECTOR/${node1}/g" ${yml_pod1} cat $yml_pod1 @@ -482,7 +482,7 @@ function tests_with_second_node() echo "####### ---> ${S} Steps on NODE2 $node2" echo "## ---> ${S}.1 Run the POD again BUT now on second node : $node2" - yml_pod2=$scripts/../deploy/scbe_volume_with_pod1.yml + yml_pod2=$scripts/deploy/scbe_volume_with_pod1.yml cp -f ${yml_pod_template} ${yml_pod2} sed -i -e "s/PODNAME/$PODName/g" -e "s/CONNAME/$CName/g" -e "s/VOLNAME/$volPODname/g" -e "s|MOUNTPATH|/data|g" -e "s/PVCNAME/$PVCName/g" -e "s/NODESELECTOR/${node2}/g" ${yml_pod2} cat $yml_pod2 @@ -597,10 +597,10 @@ S=0 # steps counter [ -n "$ACCEPTANCE_WITH_FIRST_NODE" ] && node1=$ACCEPTANCE_WITH_FIRST_NODE || { echo "env ACCEPTANCE_WITH_FIRST_NODE not provided. exit."; exit 1; } -yml_sc_tmplemt=$scripts/../deploy/scbe_volume_storage_class_template.yml -yml_pvc_template=$scripts/../deploy/scbe_volume_pvc_template.yml -yml_pod_template=$scripts/../deploy/scbe_volume_with_pod_template.yml -yml_two_vols_pod_template=$scripts/../deploy/scbe_volume_with_pod_with_2vols_template.yml +yml_sc_tmplemt=$scripts/deploy/scbe_volume_storage_class_template.yml +yml_pvc_template=$scripts/deploy/scbe_volume_pvc_template.yml +yml_pod_template=$scripts/deploy/scbe_volume_with_pod_template.yml +yml_two_vols_pod_template=$scripts/deploy/scbe_volume_with_pod_with_2vols_template.yml POSTGRES_PVC="ibm-ubiquity-db" FS_SUPPORTED="ext4 xfs" diff --git a/scripts/clean b/scripts/clean deleted file mode 100755 index 5244502cb..000000000 --- a/scripts/clean +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash - -set -e - -rm bin/* From cb41c80fa8b704f2bd8a14c530c0369c0e9d9a10 Mon Sep 17 00:00:00 2001 From: Olga Shtivelman Date: Sun, 8 Jul 2018 13:14:34 +0300 Subject: [PATCH 14/40] logging message: changed is to does --- controller/controller.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/controller/controller.go b/controller/controller.go index c24cf7129..fff3cae88 100644 --- a/controller/controller.go +++ b/controller/controller.go @@ -399,7 +399,7 @@ func (c *Controller) doUnmount(k8sPVDirectoryPath string, volumeBackend string, return c.logger.ErrorRet(err, "fail to remove slink "+k8sPVDirectoryPath) } } else { - c.logger.Info("PV directory(k8s-mountpoint) is not exist. Idempotent - skip unmount flow", + c.logger.Info("PV directory(k8s-mountpoint) does not exist. Idempotent - skip unmount flow", logs.Args{{"k8s-mountpoint", k8sPVDirectoryPath}, {"should-point-to-mountpoint", realMountedPath}}) // TODO change it to warning } return nil // Finish successfully to umount From 82497a03e30285afda9313937101cc07c5af3c20 Mon Sep 17 00:00:00 2001 From: olgashtivelman <33713489+olgashtivelman@users.noreply.github.com> Date: Mon, 9 Jul 2018 15:14:33 +0300 Subject: [PATCH 15/40] UB-1098: change info messages to warning (#202) * UB-1098: change info messages to warning for idempotent issues * --- controller/controller.go | 8 ++++---- controller/errors.go | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/controller/controller.go b/controller/controller.go index fff3cae88..9dfbf6952 100644 --- a/controller/controller.go +++ b/controller/controller.go @@ -331,7 +331,7 @@ func (c *Controller) checkSlinkBeforeUmount(k8sPVDirectoryPath string, realMount if err != nil { if c.exec.IsNotExist(err) { // The k8s PV directory not exist (its a rare case and indicate on idempotent flow) - c.logger.Info("PV directory(k8s-mountpoint) does not exist.", logs.Args{{"k8s-mountpoint", k8sPVDirectoryPath}, {"should-point-to-mountpoint", realMountedPath}}) // TODO change it to warning + c.logger.Warning("PV directory(k8s-mountpoint) does not exist.", logs.Args{{"k8s-mountpoint", k8sPVDirectoryPath}, {"should-point-to-mountpoint", realMountedPath}}) return false, nil // Idempotent flow } else { // Maybe some permissions issue @@ -399,8 +399,8 @@ func (c *Controller) doUnmount(k8sPVDirectoryPath string, volumeBackend string, return c.logger.ErrorRet(err, "fail to remove slink "+k8sPVDirectoryPath) } } else { - c.logger.Info("PV directory(k8s-mountpoint) does not exist. Idempotent - skip unmount flow", - logs.Args{{"k8s-mountpoint", k8sPVDirectoryPath}, {"should-point-to-mountpoint", realMountedPath}}) // TODO change it to warning + c.logger.Warning("PV directory(k8s-mountpoint) does not exist. Idempotent - skip unmount flow", + logs.Args{{"k8s-mountpoint", k8sPVDirectoryPath}, {"should-point-to-mountpoint", realMountedPath}}) } return nil // Finish successfully to umount } @@ -438,7 +438,7 @@ func (c *Controller) Unmount(unmountRequest k8sresources.FlexVolumeUnmountReques if volume, err = c.Client.GetVolume(getVolumeRequest); err != nil { if strings.Contains(err.Error(), resources.VolumeNotFoundErrorMsg) { warningMsg := fmt.Sprintf("%s (backend error=%v)", IdempotentUnmountSkipOnVolumeNotExistWarnigMsg, err) - c.logger.Info(warningMsg) // TODO later change to warning message + c.logger.Warning(warningMsg) return c.successFlexVolumeResponse(warningMsg) } return c.failureFlexVolumeResponse(err, "") diff --git a/controller/errors.go b/controller/errors.go index 71d364660..c7c69d003 100644 --- a/controller/errors.go +++ b/controller/errors.go @@ -78,7 +78,7 @@ func (e *k8sPVDirectoryIsNotDirNorSlinkError) Error() string { e.slink, e.fileInfo) } -const IdempotentUnmountSkipOnVolumeNotExistWarnigMsg = "Warning: Unmount operation requested to work on not exist volume. Assume its idempotent issue - so skip Unmount." +const IdempotentUnmountSkipOnVolumeNotExistWarnigMsg = "Unmount operation requested to work on not exist volume. Assume its idempotent issue - so skip Unmount." const K8sPVDirectoryIsNotSlinkErrorStr = "k8s PV directory, k8s-mountpoint, is not slink." From 3ccbbfd9a6a09b9ca394c34001153f2e4f104bca Mon Sep 17 00:00:00 2001 From: Isaac Beckman Date: Mon, 9 Jul 2018 16:43:52 +0300 Subject: [PATCH 16/40] glide.yml update with missing dependencies and improve Dockerfile to uses caching (#200) * Enable caching in Provisioner Dockerfile * Remove glide.lock from Dockerfile * Add all glide dependencies * Resolve conflicts in glide.yaml * remove glide.lock * Set ubiquity-k8s to be dependent on specific commit in ubiquity * Set versions in glide.yaml to eliminate warnings --- Dockerfile.Flex | 3 +- Dockerfile.Provisioner | 3 +- glide.yaml | 92 +++++++++++++++++++++++++++++++++++++++--- 3 files changed, 90 insertions(+), 8 deletions(-) diff --git a/Dockerfile.Flex b/Dockerfile.Flex index 0605f2318..77e487533 100644 --- a/Dockerfile.Flex +++ b/Dockerfile.Flex @@ -1,8 +1,9 @@ FROM golang:1.9.1 WORKDIR /go/src/github.com/IBM/ubiquity-k8s/ -COPY . . RUN go get -v github.com/Masterminds/glide +ADD glide.yaml . RUN glide up --strip-vendor +COPY . . RUN CGO_ENABLED=1 GOOS=linux go build -tags netgo -v -a --ldflags '-w -linkmode external -extldflags "-static"' -installsuffix cgo -o ubiquity-k8s-flex cmd/flex/main/cli.go diff --git a/Dockerfile.Provisioner b/Dockerfile.Provisioner index 4d02fe5e3..680c35707 100644 --- a/Dockerfile.Provisioner +++ b/Dockerfile.Provisioner @@ -1,8 +1,9 @@ FROM golang:1.9.1 WORKDIR /go/src/github.com/IBM/ubiquity-k8s/ -COPY . . RUN go get -v github.com/Masterminds/glide +ADD glide.yaml . RUN glide up --strip-vendor +COPY . . RUN CGO_ENABLED=1 GOOS=linux go build -tags netgo -v -a --ldflags '-w -linkmode external -extldflags "-static"' -installsuffix cgo -o ubiquity-k8s-provisioner cmd/provisioner/main/main.go diff --git a/glide.yaml b/glide.yaml index c9b6ff9d4..80a7393d1 100644 --- a/glide.yaml +++ b/glide.yaml @@ -1,22 +1,102 @@ package: github.com/IBM/ubiquity-k8s import: +- package: github.com/davecgh/go-spew + version: 04cdfd42973bb9c8589fd6a731800cf222fde1a9 +- package: github.com/djherbis/times + version: v1.0.1 +- package: github.com/ghodss/yaml + version: 73d445a93680fa1a78ae23a5839bad48f32ba1ee +- package: github.com/go-openapi/spec +- package: github.com/gogo/protobuf + version: c0656edd0d9eab7c66d1eb0c568f9039345796f7 + subpackages: + - proto + - sortkeys + - ptypes +- package: github.com/golang/glog +- package: github.com/golang/groupcache + subpackages: + - lru +- package: github.com/google/gofuzz +- package: github.com/googleapis/gnostic + version: 0c5108395e2debce0d731cf0287ddf7242066aba + subpackages: + - OpenAPIv2 +- package: github.com/gorilla/mux + version: v1.5.0 +- package: github.com/gregjones/httpcache + subpackages: + - diskcache +- package: github.com/hashicorp/golang-lru +- package: github.com/howeyc/gopass +- package: github.com/imdario/mergo + version: 6633656539c1639d9d78127b7d47c622b5d7b6dc +- package: github.com/jinzhu/gorm + version: v1.0 +- package: github.com/json-iterator/go + version: 36b14963da70d11297d313183d7e6388c8510e1e +- package: github.com/juju/ratelimit + version: 5b9ff866471762aa2ab2dced63c9fb6f53921342 +- package: github.com/natefinch/lumberjack + version: aee4629129445bbdfb69aa565537dcfa16544311 +- package: github.com/op/go-logging + version: 970db520ece77730c7e4724c61121037378659d9 +- package: github.com/pborman/uuid + version: ca53cad383cad2479bbba7f7a1a05797ec1386e4 +- package: github.com/peterbourgon/diskv + version: 5f041e8faa004a95c88a202771f4cc3e991971e6 +- package: github.com/spf13/pflag + version: 5ccb023bc27df288a957c5e994cd44fd19619465 +- package: k8s.io/kube-openapi + subpackages: + - pkg/common + - pkg/util/proto +- package: golang.org/x/net +- package: github.com/jinzhu/inflection +- package: github.com/gorilla/context + version: v1.1.1 +- package: github.com/go-openapi/jsonpointer +- package: github.com/go-openapi/jsonreference +- package: github.com/go-openapi/swag +- package: gopkg.in/inf.v0 +- package: github.com/emicklei/go-restful + version: ff4f55a206334ef123e4f79bbf348980da81ca46 +- package: golang.org/x/crypto +- package: golang.org/x/sys +- package: github.com/PuerkitoBio/purell + version: 8a290539e2e8629dbc4e6bad948158f790ec31f4 +- package: github.com/mailru/easyjson +- package: gopkg.in/yaml.v2 + version: 53feefa2559fb8dfa8d81baad31be332c97d6c77 +- package: golang.org/x/text +- package: github.com/google/btree +- package: github.com/lib/pq +- package: github.com/PuerkitoBio/urlesc +- package: github.com/modern-go/concurrent + version: 1.0.3 +- package: github.com/modern-go/reflect2 + version: 1.0.0 +- package: github.com/golang/protobuf + version: 1643683e1b54a9e88ad26d98f81400c8c9d9f4f9 + subpackages: + - proto - package: github.com/BurntSushi/toml version: v0.3.0 - package: github.com/jessevdk/go-flags - version: f88afde2fa19a30cf50ba4b05b3d13bc6bae3079 + version: v1.4.0 - package: github.com/kubernetes-incubator/external-storage version: 92295a30e0ec7da80c41c1f50f9301f3adee4556 subpackages: - lib - package: github.com/IBM/ubiquity - version: dev + version: 44f3c73fb38e02616320f923024b5ae213643137 subpackages: - remote - resources - utils - fakes - package: k8s.io/apimachinery - version: kubernetes-1.9.8 + version: kubernetes-1.9.2 subpackages: - pkg/api/errors - pkg/api/resource @@ -30,7 +110,7 @@ import: - pkg/util/wait - pkg/watch - package: k8s.io/client-go - version: v6.0.0 + version: kubernetes-1.9.2 subpackages: - kubernetes - kubernetes/typed/core/v1 @@ -41,9 +121,9 @@ import: - tools/remotecommand - tools/reference - package: k8s.io/api - version: kubernetes-1.9.8 + version: kubernetes-1.9.2 - package: k8s.io/kubernetes - version: v1.9.8 + version: v1.9.2 subpackages: - pkg/util/goroutinemap - pkg/util/version From 2fbda993bb46bf1921602f7cf4206eefe6cb0b91 Mon Sep 17 00:00:00 2001 From: Olga Shtivelman Date: Mon, 9 Jul 2018 16:49:17 +0300 Subject: [PATCH 17/40] Fixed logging message syntax --- controller/controller.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/controller/controller.go b/controller/controller.go index fff3cae88..a712331f4 100644 --- a/controller/controller.go +++ b/controller/controller.go @@ -620,7 +620,7 @@ func (c *Controller) doAfterMount(mountRequest k8sresources.FlexVolumeMountReque if err != nil { if c.exec.IsNotExist(err) { // The k8s PV directory not exist (its a rare case and indicate on idempotent flow) - c.logger.Info("PV directory(k8s-mountpoint) nor slink are not exist. Idempotent - skip delete PV directory(k8s-mountpoint).", logs.Args{{"k8s-mountpoint", k8sPVDirectoryPath}, {"should-point-to-mountpoint", mountedPath}}) + c.logger.Info("PV directory(k8s-mountpoint) nor slink do not exist. Idempotent - skip delete PV directory(k8s-mountpoint).", logs.Args{{"k8s-mountpoint", k8sPVDirectoryPath}, {"should-point-to-mountpoint", mountedPath}}) c.logger.Info("Creating slink(k8s-mountpoint) that point to mountpoint", logs.Args{{"k8s-mountpoint", k8sPVDirectoryPath}, {"mountpoint", mountedPath}}) err = c.exec.Symlink(mountedPath, k8sPVDirectoryPath) if err != nil { From 2bbb2accb4f2459c5497fea77c6d543c922b640c Mon Sep 17 00:00:00 2001 From: olgashtivelman <33713489+olgashtivelman@users.noreply.github.com> Date: Mon, 9 Jul 2018 17:36:09 +0300 Subject: [PATCH 18/40] =?UTF-8?q?UB-1001:=20fix=20idempotent=20-=20calling?= =?UTF-8?q?=20detach=20with=20an=20empty=20host=20->=20not=20at=E2=80=A6?= =?UTF-8?q?=20(#197)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * UB-1001: fix idempotent issue : when calling detach with an empty host will return not attached response* --- controller/controller.go | 9 ++++++++- controller/controller_test.go | 36 +++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/controller/controller.go b/controller/controller.go index 9dfbf6952..a2e316239 100644 --- a/controller/controller.go +++ b/controller/controller.go @@ -771,7 +771,9 @@ func (c *Controller) doDetach(detachRequest k8sresources.FlexVolumeDetachRequest return nil } } + host := detachRequest.Host + if host == "" { // only when triggered during unmount var err error @@ -779,9 +781,14 @@ func (c *Controller) doDetach(detachRequest k8sresources.FlexVolumeDetachRequest if err != nil { return c.logger.ErrorRet(err, "getHostAttached failed") } + + if host == "" { + // this means that the host is not attached to anything so no reason to call detach + c.logger.Warning(fmt.Sprintf("Vol: %s is not attahced to any host. so no detach action is called.", detachRequest.Name)) + return nil + } } - // TODO idempotent, don't trigger Detach if host is empty (even after getHostAttached) ubDetachRequest := resources.DetachRequest{Name: detachRequest.Name, Host: host, Context: detachRequest.Context} err := c.Client.Detach(ubDetachRequest) if err != nil { diff --git a/controller/controller_test.go b/controller/controller_test.go index 1a10486b7..7f12febaa 100644 --- a/controller/controller_test.go +++ b/controller/controller_test.go @@ -22,6 +22,7 @@ import ( "encoding/json" "fmt" + ctl "github.com/IBM/ubiquity-k8s/controller" k8sresources "github.com/IBM/ubiquity-k8s/resources" "github.com/IBM/ubiquity/fakes" @@ -933,4 +934,39 @@ var _ = Describe("Controller", func() { }) }) */ + Context(".Detach", func() { + BeforeEach(func() { + + }) + It("calling detach works as expected when volume is attached to the host", func() { + dat := make(map[string]interface{}) + host := "host1" + dat[resources.ScbeKeyVolAttachToHost] = host + fakeClient.GetVolumeConfigReturns(dat, nil) + unmountRequest := k8sresources.FlexVolumeDetachRequest{"vol1", host, "version", resources.RequestContext{}} + controller.Detach(unmountRequest) + Expect(fakeClient.DetachArgsForCall(0).Host).To(Equal(host)) + + }) + It("should not call detach if volume is not attached to the host", func() { + dat := make(map[string]interface{}) + host := "host1" + dat[resources.ScbeKeyVolAttachToHost] = "" + fakeClient.GetVolumeConfigReturns(dat, nil) + unmountRequest := k8sresources.FlexVolumeDetachRequest{"vol1", host, "version", resources.RequestContext{}} + controller.Detach(unmountRequest) + Expect(fakeClient.DetachCallCount()).To(Equal(0)) + }) + It("should not call detach if volume is empty and not attached", func() { + dat := make(map[string]interface{}) + host := "" + dat[resources.ScbeKeyVolAttachToHost] = host + fakeClient.GetVolumeConfigReturns(dat, nil) + unmountRequest := k8sresources.FlexVolumeDetachRequest{"vol1", host, "version", resources.RequestContext{}} + controller.Detach(unmountRequest) + Expect(fakeClient.DetachCallCount()).To(Equal(0)) + }) + + //TODO: need to test the path to doDetach with an empty host further via the umount tests (when they are merged) + }) }) From f5c2a304f3dea88bf5ca22fcc6df681d0c2c9379 Mon Sep 17 00:00:00 2001 From: olgashtivelman <33713489+olgashtivelman@users.noreply.github.com> Date: Sun, 15 Jul 2018 11:14:18 +0300 Subject: [PATCH 19/40] Fix/ub 1325 adda action name to the logs (#199) this PR will add an action name to each log line. (for example all oprerations that are part of Delete will have the request-action name in the log. like : fd5dd389-7acb-11e8-88cd-54ee75515403-Delete ) --- cmd/flex/main/cli.go | 17 ++++++++--------- controller/controller.go | 2 +- glide.yaml | 2 +- volume/provision.go | 8 ++++---- 4 files changed, 14 insertions(+), 15 deletions(-) diff --git a/cmd/flex/main/cli.go b/cmd/flex/main/cli.go index 64bfbc517..8b268abb0 100644 --- a/cmd/flex/main/cli.go +++ b/cmd/flex/main/cli.go @@ -90,7 +90,7 @@ func (a *AttachCommand) Execute(args []string) error { var version string var hostname string - requestContext := logs.GetNewRequestContext() + requestContext := logs.GetNewRequestContext("Attach") if len(args) < 1 { @@ -152,8 +152,7 @@ type WaitForAttachCommand struct { } func (wfa *WaitForAttachCommand) Execute(args []string) error { - requestContext := logs.GetNewRequestContext() - + requestContext := logs.GetNewRequestContext("WaitForAttach") if len(args) < 2 { response := k8sresources.FlexVolumeResponse{ @@ -193,7 +192,7 @@ type IsAttachedCommand struct { } func (d *IsAttachedCommand) Execute(args []string) error { - requestContext := logs.GetNewRequestContext() + requestContext := logs.GetNewRequestContext("IsAttached") if len(args) < 2 { response := k8sresources.FlexVolumeResponse{ @@ -234,7 +233,7 @@ type DetachCommand struct { } func (d *DetachCommand) Execute(args []string) error { - requestContext := logs.GetNewRequestContext() + requestContext := logs.GetNewRequestContext("Detach") var hostname string var version string if len(args) < 1 { @@ -280,7 +279,7 @@ type MountDeviceCommand struct { } func (d *MountDeviceCommand) Execute(args []string) error { - requestContext := logs.GetNewRequestContext() + requestContext := logs.GetNewRequestContext("MountDevice") if len(args) < 3 { response := k8sresources.FlexVolumeResponse{ @@ -320,7 +319,7 @@ type UnmountDeviceCommand struct { } func (d *UnmountDeviceCommand) Execute(args []string) error { - requestContext := logs.GetNewRequestContext() + requestContext := logs.GetNewRequestContext("UnmountDevice") if len(args) < 1 { response := k8sresources.FlexVolumeResponse{ @@ -359,7 +358,7 @@ func (m *MountCommand) Execute(args []string) error { var ok bool var version string - requestContext := logs.GetNewRequestContext() + requestContext := logs.GetNewRequestContext("Mount") //should error out when not enough args if len(args) < 2 { @@ -439,7 +438,7 @@ type UnmountCommand struct { } func (u *UnmountCommand) Execute(args []string) error { - requestContext := logs.GetNewRequestContext() + requestContext := logs.GetNewRequestContext("Unmount") if len(args) < 1 { response := k8sresources.FlexVolumeResponse{ diff --git a/controller/controller.go b/controller/controller.go index a2e316239..f23baf3b2 100644 --- a/controller/controller.go +++ b/controller/controller.go @@ -620,7 +620,7 @@ func (c *Controller) doAfterMount(mountRequest k8sresources.FlexVolumeMountReque if err != nil { if c.exec.IsNotExist(err) { // The k8s PV directory not exist (its a rare case and indicate on idempotent flow) - c.logger.Info("PV directory(k8s-mountpoint) nor slink are not exist. Idempotent - skip delete PV directory(k8s-mountpoint).", logs.Args{{"k8s-mountpoint", k8sPVDirectoryPath}, {"should-point-to-mountpoint", mountedPath}}) + c.logger.Info("PV directory(k8s-mountpoint) nor slink do not exist. Idempotent - skip delete PV directory(k8s-mountpoint).", logs.Args{{"k8s-mountpoint", k8sPVDirectoryPath}, {"should-point-to-mountpoint", mountedPath}}) c.logger.Info("Creating slink(k8s-mountpoint) that point to mountpoint", logs.Args{{"k8s-mountpoint", k8sPVDirectoryPath}, {"mountpoint", mountedPath}}) err = c.exec.Symlink(mountedPath, k8sPVDirectoryPath) if err != nil { diff --git a/glide.yaml b/glide.yaml index 80a7393d1..dc82a1136 100644 --- a/glide.yaml +++ b/glide.yaml @@ -89,7 +89,7 @@ import: subpackages: - lib - package: github.com/IBM/ubiquity - version: 44f3c73fb38e02616320f923024b5ae213643137 + version: 490b484a3484811cdb85691b53013ddeede9b24a subpackages: - remote - resources diff --git a/volume/provision.go b/volume/provision.go index 20b42580b..880362de0 100644 --- a/volume/provision.go +++ b/volume/provision.go @@ -64,7 +64,7 @@ func NewFlexProvisioner(logger *log.Logger, ubiquityClient resources.StorageClie func newFlexProvisionerInternal(logger *log.Logger, ubiquityClient resources.StorageClient, config resources.UbiquityPluginConfig) (*flexProvisioner, error) { var identity types.UID identityPath := path.Join(config.LogPath, identityFile) - request_context := logs.GetNewRequestContext() + request_context := logs.GetNewRequestContext("Activate") if _, err := os.Stat(identityPath); os.IsNotExist(err) { identity = uuid.NewUUID() err := ioutil.WriteFile(identityPath, []byte(identity), 0600) @@ -118,7 +118,7 @@ type flexProvisioner struct { // Provision creates a volume i.e. the storage asset and returns a PV object for // the volume. func (p *flexProvisioner) Provision(options controller.VolumeOptions) (*v1.PersistentVolume, error) { - request_context := logs.GetNewRequestContext() + request_context := logs.GetNewRequestContext("Provision") go_id := logs.GetGoID() logs.GoIdToRequestIdMap.Store(go_id, request_context) defer logs.GetDeleteFromMapFunc(go_id) @@ -180,8 +180,8 @@ func (p *flexProvisioner) Provision(options controller.VolumeOptions) (*v1.Persi // Delete removes the directory that was created by Provision backing the given // PV. func (p *flexProvisioner) Delete(volume *v1.PersistentVolume) error { - requestContext := logs.GetNewRequestContext() - go_id := logs.GetGoID() + requestContext := logs.GetNewRequestContext("Delete") + go_id := logs.GetGoID() logs.GoIdToRequestIdMap.Store(go_id, requestContext) defer logs.GetDeleteFromMapFunc(go_id) defer p.logger.Trace(logs.DEBUG, logs.Args{{"volume name", volume.Name}})() From 631352063485a43bcae2bc977defef7307fb5f07 Mon Sep 17 00:00:00 2001 From: Isaac Beckman Date: Mon, 16 Jul 2018 14:34:50 +0300 Subject: [PATCH 20/40] Align ubiquity-k8s with ubiquity in glide.yaml --- glide.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/glide.yaml b/glide.yaml index dc82a1136..74cb3b925 100644 --- a/glide.yaml +++ b/glide.yaml @@ -89,7 +89,7 @@ import: subpackages: - lib - package: github.com/IBM/ubiquity - version: 490b484a3484811cdb85691b53013ddeede9b24a + version: e18041dfa8078a179672c3e187fa78b1d81de230 subpackages: - remote - resources From a943e43fa896bcc9efdfaaac3642ef550c17dfb7 Mon Sep 17 00:00:00 2001 From: Olga Shtivelman Date: Mon, 16 Jul 2018 17:36:52 +0300 Subject: [PATCH 21/40] using latest ubiquity dev commit# --- glide.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/glide.yaml b/glide.yaml index 74cb3b925..d94cebce4 100644 --- a/glide.yaml +++ b/glide.yaml @@ -89,7 +89,7 @@ import: subpackages: - lib - package: github.com/IBM/ubiquity - version: e18041dfa8078a179672c3e187fa78b1d81de230 + version: 4572f66374faf977fe4f70fb3f74c4cb69b5dec0 subpackages: - remote - resources From a0e0b40702a6094273cf728f4fc00545bf88b280 Mon Sep 17 00:00:00 2001 From: Shay Berman Date: Sun, 22 Jul 2018 15:38:38 +0300 Subject: [PATCH 22/40] Fix tolerations flex-daemonset.yml to operator:Exists for ICP 2.1.0.2+ support --- .../yamls/ubiquity-k8s-flex-daemonset.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/scripts/installer-for-ibm-storage-enabler-for-containers/yamls/ubiquity-k8s-flex-daemonset.yml b/scripts/installer-for-ibm-storage-enabler-for-containers/yamls/ubiquity-k8s-flex-daemonset.yml index 2e0dd02af..001acc352 100644 --- a/scripts/installer-for-ibm-storage-enabler-for-containers/yamls/ubiquity-k8s-flex-daemonset.yml +++ b/scripts/installer-for-ibm-storage-enabler-for-containers/yamls/ubiquity-k8s-flex-daemonset.yml @@ -17,8 +17,7 @@ spec: tolerations: # Create flex Pods also on master nodes (even if there are NoScheduled nodes) # Some k8s versions use dedicated key for toleration of the master and some use node-role.kubernetes.io/master key. - key: dedicated - operator: Equal - value: master + operator: Exists effect: NoSchedule - key: node-role.kubernetes.io/master effect: NoSchedule From c1328096a834015317f838ffe620af83372d749e Mon Sep 17 00:00:00 2001 From: Olga Shtivelman Date: Tue, 24 Jul 2018 14:08:29 +0300 Subject: [PATCH 23/40] UB-1433: update commit# to use the new warning log changes in ubiquity project --- glide.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/glide.yaml b/glide.yaml index d94cebce4..14af40ceb 100644 --- a/glide.yaml +++ b/glide.yaml @@ -89,7 +89,7 @@ import: subpackages: - lib - package: github.com/IBM/ubiquity - version: 4572f66374faf977fe4f70fb3f74c4cb69b5dec0 + version: 0246249a321902ddc1901f732d683fe5819b37ec subpackages: - remote - resources From 186fbd2b61d7695aaf6eede5476241b02cc596de Mon Sep 17 00:00:00 2001 From: Olga Shtivelman Date: Sun, 5 Aug 2018 15:58:27 +0300 Subject: [PATCH 24/40] UB-1405: update commit# - fixed: unmount flow should not fail if discovery fails --- glide.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/glide.yaml b/glide.yaml index 14af40ceb..77dff8360 100644 --- a/glide.yaml +++ b/glide.yaml @@ -89,7 +89,7 @@ import: subpackages: - lib - package: github.com/IBM/ubiquity - version: 0246249a321902ddc1901f732d683fe5819b37ec + version: 8d65f6fc29673197ee06e80afbabc6f2453094ff subpackages: - remote - resources From 2c1bb51daf4f7800f14cf28820bc6c059b1109d0 Mon Sep 17 00:00:00 2001 From: Olga Shtivelman Date: Mon, 6 Aug 2018 11:54:41 +0300 Subject: [PATCH 25/40] Changed ubiquity commit# after fixing a typo --- glide.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/glide.yaml b/glide.yaml index 77dff8360..89bedab90 100644 --- a/glide.yaml +++ b/glide.yaml @@ -89,7 +89,7 @@ import: subpackages: - lib - package: github.com/IBM/ubiquity - version: 8d65f6fc29673197ee06e80afbabc6f2453094ff + version: 7611848ebb777a726ab2ad2ad78617bf1c0c6331 subpackages: - remote - resources From 59b6a96551b721aba46b0cad951c1cca4f6b32b3 Mon Sep 17 00:00:00 2001 From: olgashtivelman <33713489+olgashtivelman@users.noreply.github.com> Date: Wed, 8 Aug 2018 17:13:04 +0300 Subject: [PATCH 26/40] Fix/ub 1349 not allow the attachment of two pods to one pvc (#204) This PR is to not allow attachement of 2 pods to one PVC. currently this is allowed due to a fix of another idempotent issue. we are checking if a PVC is already attached to another pod using the slinks - in the mount process we check if the /ubiquity/volume is already linked to a pod that is not the current pod - if so then we will fail the mount process. also a mountlock is added to prevent operations during the mount happening for 2 different pods (and same PVC) --- cmd/flex/main/cli.go | 3 +- controller/controller.go | 156 ++++++++++++++++++++----- controller/controller_internal_test.go | 108 +++++++++++++++++ controller/controller_test.go | 47 +++++--- controller/errors.go | 22 ++++ glide.yaml | 2 +- 6 files changed, 297 insertions(+), 41 deletions(-) create mode 100644 controller/controller_internal_test.go diff --git a/cmd/flex/main/cli.go b/cmd/flex/main/cli.go index 8b268abb0..bc90119d9 100644 --- a/cmd/flex/main/cli.go +++ b/cmd/flex/main/cli.go @@ -597,4 +597,5 @@ func printResponse(f k8sresources.FlexVolumeResponse) error { } fmt.Printf("%s", string(responseBytes[:])) return nil -} \ No newline at end of file +} + diff --git a/controller/controller.go b/controller/controller.go index f23baf3b2..4c2f3b9af 100644 --- a/controller/controller.go +++ b/controller/controller.go @@ -33,9 +33,13 @@ import ( "github.com/IBM/ubiquity/utils/logs" "github.com/nightlyone/lockfile" ) - -const FlexSuccessStr = "Success" -const FlexFailureStr = "Failure" + +const( + K8sPodsDirecotryName = "pods" + k8sMountPointvolumeDirectoryName = "ibm~ubiquity-k8s-flex" + FlexSuccessStr = "Success" + FlexFailureStr = "Failure" +) //Controller this is a structure that controls volume management type Controller struct { @@ -49,46 +53,38 @@ type Controller struct { mounterFactory mounter.MounterFactory } -//NewController allows to instantiate a controller -func NewController(logger *log.Logger, config resources.UbiquityPluginConfig) (*Controller, error) { +func newController(logger *log.Logger, config resources.UbiquityPluginConfig, client resources.StorageClient, exec utils.Executor, mFactory mounter.MounterFactory) (*Controller, error) { unmountFlock, err := lockfile.New(filepath.Join(os.TempDir(), "ubiquity.unmount.lock")) if err != nil { panic(err) } - remoteClient, err := remote.NewRemoteClientSecure(logger, config) - if err != nil { - return nil, err - } return &Controller{ logger: logs.GetLogger(), legacyLogger: logger, - Client: remoteClient, - exec: utils.NewExecutor(), + Client: client, + exec: exec, config: config, mounterPerBackend: make(map[string]resources.Mounter), unmountFlock: unmountFlock, - mounterFactory: mounter.NewMounterFactory(), + mounterFactory: mFactory, }, nil } -//NewControllerWithClient is made for unit testing purposes where we can pass a fake client -func NewControllerWithClient(logger *log.Logger, config resources.UbiquityPluginConfig, client resources.StorageClient, exec utils.Executor, mFactory mounter.MounterFactory) *Controller { - unmountFlock, err := lockfile.New(filepath.Join(os.TempDir(), "ubiquity.unmount.lock")) +//NewController allows to instantiate a controller +func NewController(logger *log.Logger, config resources.UbiquityPluginConfig) (*Controller, error) { + remoteClient, err := remote.NewRemoteClientSecure(logger, config) if err != nil { - panic(err) + return nil, err } + + return newController(logger, config, remoteClient, utils.NewExecutor(), mounter.NewMounterFactory()) +} - return &Controller{ - logger: logs.GetLogger(), - legacyLogger: logger, - Client: client, - exec: exec, - config: config, - mounterPerBackend: make(map[string]resources.Mounter), - unmountFlock: unmountFlock, - mounterFactory: mFactory, - } +//NewControllerWithClient is made for unit testing purposes where we can pass a fake client +func NewControllerWithClient(logger *log.Logger, config resources.UbiquityPluginConfig, client resources.StorageClient, exec utils.Executor, mFactory mounter.MounterFactory) *Controller { + controller, _ := newController(logger, config, client, exec, mFactory) + return controller } //Init method is to initialize the k8sresourcesvolume @@ -267,6 +263,7 @@ func (c *Controller) UnmountDevice(unmountDeviceRequest k8sresources.FlexVolumeU return response } + //Mount method allows to mount the volume/fileset to a given location for a pod func (c *Controller) Mount(mountRequest k8sresources.FlexVolumeMountRequest) k8sresources.FlexVolumeResponse { go_id := logs.GetGoID() @@ -275,7 +272,24 @@ func (c *Controller) Mount(mountRequest k8sresources.FlexVolumeMountRequest) k8s defer c.logger.Trace(logs.DEBUG)() var response k8sresources.FlexVolumeResponse c.logger.Debug("", logs.Args{{"request", mountRequest}}) + + flockName := fmt.Sprintf("ubiquity.mount.%s.lock", mountRequest.MountDevice) + mountFlock, err := lockfile.New(filepath.Join(os.TempDir(), flockName )) + if err != nil { + panic(err) + } + for { + err := mountFlock.TryLock() + if err == nil { + break + } + c.logger.Debug("mountFlock.TryLock failed", logs.Args{{"error", err}}) + time.Sleep(time.Duration(500 * time.Millisecond)) + } + c.logger.Debug("Got mountFlock for volume.", logs.Args{{"volume", mountRequest.MountDevice}}) + defer mountFlock.Unlock() + // TODO check if volume exist first and what its backend type mountedPath, err := c.doMount(mountRequest) if err != nil { @@ -541,6 +555,91 @@ func (c *Controller) getMounterByPV(mountRequest k8sresources.FlexVolumeMountReq return mounter, nil } +func getK8sPodsBaseDir(k8sMountPoint string) (string, error ){ + /* + function is going to get from this kind of dir: + /var/lib/kubelet/pods/1f94f1d9-8f36-11e8-b227-005056a4d4cb/volumes/ibm~ubiquity-k8s-flex/... + to /var/lib/kubelet/pods/ + note: /var/lib can be changed in configuration so we need to get the base dir at runtime + */ + tempMountPoint := k8sMountPoint + for i := 0 ; i < 4 ; i++ { + tempMountPoint = filepath.Dir(tempMountPoint) + } + + if filepath.Base(tempMountPoint) != K8sPodsDirecotryName{ + return "", &WrongK8sDirectoryPathError{k8sMountPoint} + } + + return tempMountPoint, nil +} + +func checkSlinkAlreadyExistsOnMountPoint(mountPoint string, k8sMountPoint string, logger logs.Logger, executer utils.Executor) (error){ + /* + the mountpoint parameter is the actual mountpoint we are pointing to: /ubiquity/WWN + the k8sMountPoint is the path to the link we want to create from the /var/lib/kubelet directory to the mountpoint + */ + defer logger.Trace(logs.INFO, logs.Args{{"mountPoint", mountPoint}, {"k8sMountPoint", k8sMountPoint}})() + + k8sBaseDir, err := getK8sPodsBaseDir(k8sMountPoint) + if err != nil{ + return logger.ErrorRet(err, "Failed to get k8s pods base dir.", logs.Args{{"k8sMountPoint", k8sMountPoint}}) + } + + file_pattern := filepath.Join(k8sBaseDir, "*","volumes", k8sMountPointvolumeDirectoryName,"*") + files, err := executer.GetGlobFiles(file_pattern) + if err != nil{ + return logger.ErrorRet(err, "Failed to get files that match the pattern.", logs.Args{{"file_pattern", file_pattern}}) + } + + slinks := []string{} + if len(files) == 0 { + logger.Debug("There is no Pod that uses ibm flex PV on this node (No files matched the given pattern were found).", logs.Args{{"pattern", file_pattern}}) + return nil + } + + mountStat, err := executer.Stat(mountPoint) + if err != nil { + if os.IsNotExist(err){ + logger.Debug("Mount point path does not exist yet.", logs.Args{{"mountpoint",mountPoint}}) + return nil + } + return logger.ErrorRet(err, "Failed to get stat for mount point file.", logs.Args{{"file", mountPoint}}) + } + + // go over the files and check if any of them is the same as our destinated mountpoint + // this checks if any of the solinks are pointing to the PV we want to mount. + for _, file := range files { + fileStat, err := executer.Stat(file) + if err != nil{ + logger.Warning("Failed to get stat for file.", logs.Args{{"file", file}}) + continue + } + + isSameFile := executer.IsSameFile(fileStat, mountStat) + if isSameFile{ + slinks = append(slinks, file) + } + } + + if len(slinks) == 0 { + logger.Debug("There were no soft links pointing to given mountpoint.", logs.Args{{"mountpoint", mountPoint}}) + return nil + } + + if len(slinks) > 1 { + return logger.ErrorRet(&PVIsAlreadyUsedByAnotherPod{mountPoint, slinks}, "More then 1 soft link was pointing to mountpoint.") + } + + slink := slinks[0] + if slink != k8sMountPoint{ + return logger.ErrorRet(&PVIsAlreadyUsedByAnotherPod{mountPoint, slinks}, "PV is used by another pod.") + } + + return nil +} + + func (c *Controller) doMount(mountRequest k8sresources.FlexVolumeMountRequest) (string, error) { defer c.logger.Trace(logs.DEBUG)() @@ -558,6 +657,11 @@ func (c *Controller) doMount(mountRequest k8sresources.FlexVolumeMountRequest) ( if err != nil { return "", c.logger.ErrorRet(err, "prepareUbiquityMountRequest failed") } + + err = checkSlinkAlreadyExistsOnMountPoint(ubMountRequest.Mountpoint, mountRequest.MountPath, c.logger, c.exec) + if err != nil { + return "", c.logger.ErrorRet(err, "Failed to check if other links point to mountpoint") + } mountpoint, err := mounter.Mount(ubMountRequest) if err != nil { diff --git a/controller/controller_internal_test.go b/controller/controller_internal_test.go new file mode 100644 index 000000000..1676f5be5 --- /dev/null +++ b/controller/controller_internal_test.go @@ -0,0 +1,108 @@ +package controller + +/** + These tests are not in controller_test.go because they have to be inside the package of + the module they are testing so that it will be possible to test not exporeted functions. +**/ + +import ( + "fmt" + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + "github.com/IBM/ubiquity/utils/logs" + "github.com/IBM/ubiquity/fakes" +) + + + +var _ = Describe("controller_internal_tests", func() { + Context(".getK8sBaseDir", func() { + It("should succeed if path is correct", func() { + res, err := getK8sPodsBaseDir("/var/lib/kubelet/pods/1f94f1d9-8f36-11e8-b227-005056a4d4cb/volumes/ibm~ubiquity-k8s-flex/pvc-123") + Expect(err).NotTo(HaveOccurred()) + Expect(res).To(Equal("/var/lib/kubelet/pods")) + }) + It("should succeed if path is correct and not default", func() { + res, err := getK8sPodsBaseDir("/tmp/kubelet/pods/1f94f1d9-8f36-11e8-b227-005056a4d4cb/volumes/ibm~ubiquity-k8s-flex/pvc-123") + Expect(err).NotTo(HaveOccurred()) + Expect(res).To(Equal("/tmp/kubelet/pods")) + }) + It("should fail if path is not of correct structure", func() { + k8smountpoint := "/tmp/kubelet/soemthing/1f94f1d9-8f36-11e8-b227-005056a4d4cb/volumes/ibm~ubiquity-k8s-flex/pvc-123" + res, err := getK8sPodsBaseDir(k8smountpoint) + Expect(err).To(HaveOccurred()) + Expect(err).To(Equal(&WrongK8sDirectoryPathError{k8smountpoint})) + Expect(res).To(Equal("")) + }) + It("should fail if path is not of correct structure", func() { + k8smountpoint := "/tmp/kubelet/soemthing/pods/1f94f1d9-8f36-11e8-b227-005056a4d4cb/volumes/ibm~ubiquity-k8s-flex" + res, err := getK8sPodsBaseDir(k8smountpoint) + Expect(err).To(HaveOccurred()) + Expect(err).To(Equal(&WrongK8sDirectoryPathError{k8smountpoint})) + Expect(res).To(Equal("")) + }) + }) + Context(".checkSlinkAlreadyExistsOnMountPoint", func() { + var ( + fakeExecutor *fakes.FakeExecutor + mountPoint string + ) + BeforeEach(func() { + fakeExecutor = new(fakes.FakeExecutor) + mountPoint = "/tmp/kubelet/pods/1f94f1d9-8f36-11e8-b227-005056a4d4cb/volumes/ibm~ubiquity-k8s-flex/pvc-123" + }) + It("should return no error if it is the first volume", func() { + fakeExecutor.GetGlobFilesReturns([]string{}, nil) + err := checkSlinkAlreadyExistsOnMountPoint("mountPoint", mountPoint, logs.GetLogger(), fakeExecutor) + Expect(err).To(BeNil()) + }) + It("should return no error if there are no other links", func() { + fakeExecutor.GetGlobFilesReturns([]string{"/tmp/file1", "/tmp/file2"}, nil) + fakeExecutor.IsSameFileReturns(false) + err:= checkSlinkAlreadyExistsOnMountPoint("mountPoint",mountPoint, logs.GetLogger(), fakeExecutor) + Expect(err).To(BeNil()) + }) + It("should return an error if this mountpoint already has links", func() { + file := "/tmp/file1" + fakeExecutor.GetGlobFilesReturns([]string{file}, nil) + fakeExecutor.IsSameFileReturns(true) + err:= checkSlinkAlreadyExistsOnMountPoint("mountPoint", mountPoint, logs.GetLogger(), fakeExecutor) + Expect(err).ToNot(BeNil()) + Expect(err).To(Equal(&PVIsAlreadyUsedByAnotherPod{"mountPoint", []string{file}})) + }) + It("should return no errors if this mountpoint has only one links and it is the current pvc", func() { + file := mountPoint + fakeExecutor.GetGlobFilesReturns([]string{file}, nil) + fakeExecutor.IsSameFileReturns(true) + err := checkSlinkAlreadyExistsOnMountPoint("mountPoint", file, logs.GetLogger(), fakeExecutor) + Expect(err).To(BeNil()) + }) + It("should return error if getk8sbaseDir returns an error", func() { + k8sMountPoint := "/tmp/kubelet/something" + err := checkSlinkAlreadyExistsOnMountPoint("mountPoint", k8sMountPoint, logs.GetLogger(), fakeExecutor) + Expect(err).To(Equal(&WrongK8sDirectoryPathError{k8sMountPoint})) + }) + It("should return error if glob returns an error", func() { + errstrObj := fmt.Errorf("An error ooccured") + fakeExecutor.GetGlobFilesReturns(nil, errstrObj) + err := checkSlinkAlreadyExistsOnMountPoint("mountPoint", mountPoint, logs.GetLogger(), fakeExecutor) + Expect(err).To(Equal(errstrObj)) + + }) + It("should return error if stat function on the mountpoint returns an error", func() { + errstrObj := fmt.Errorf("An error ooccured") + fakeExecutor.GetGlobFilesReturns([]string{"/tmp/file1"}, nil) + fakeExecutor.StatReturns(nil, errstrObj) + err:= checkSlinkAlreadyExistsOnMountPoint("mountPoint", mountPoint, logs.GetLogger(), fakeExecutor) + Expect(err).To(Equal(errstrObj)) + }) + It("should continue if stat on a link returns an error", func() { + errstrObj := fmt.Errorf("An error ooccured") + fakeExecutor.GetGlobFilesReturns([]string{"/tmp/file1"}, nil) + fakeExecutor.StatReturnsOnCall(1, nil, errstrObj) + err := checkSlinkAlreadyExistsOnMountPoint("mountPoint", mountPoint, logs.GetLogger(), fakeExecutor) + Expect(err).ToNot(HaveOccurred()) + }) + }) +}) + diff --git a/controller/controller_test.go b/controller/controller_test.go index 7f12febaa..48123a185 100644 --- a/controller/controller_test.go +++ b/controller/controller_test.go @@ -39,6 +39,7 @@ var _ = Describe("Controller", func() { fakeMounter *fakes.FakeMounter ubiquityConfig resources.UbiquityPluginConfig dat map[string]interface{} + mountPoint string ) BeforeEach(func() { fakeExec = new(fakes.FakeExecutor) @@ -51,6 +52,7 @@ var _ = Describe("Controller", func() { if err := json.Unmarshal(byt, &dat); err != nil { panic(err) } + mountPoint = "/tmp/kubelet/pods/1f94f1d9-8f36-11e8-b227-005056a4d4cb/volumes/ibm~ubiquity-k8s-flex/pvc-123" }) @@ -116,6 +118,15 @@ var _ = Describe("Controller", func() { // }) }) Context(".Mount", func() { + var ( + extraParams map[string]interface{} + controller *ctl.Controller + ) + BeforeEach(func(){ + extraParams = make(map[string]interface{}) + extraParams["pv"] = "volume_name" + controller = ctl.NewControllerWithClient(testLogger, ubiquityConfig, fakeClient, fakeExec, fakeMounterFactory) + }) It("should fail if k8s version < 1.6 (doMount)", func() { mountRequest := k8sresources.FlexVolumeMountRequest{MountPath: "fake", MountDevice: "pv1", Opts: map[string]string{"Wwn": "fake"}, Version: k8sresources.KubernetesVersion_1_5} @@ -127,7 +138,7 @@ var _ = Describe("Controller", func() { }) It("should fail in GetVolume if volume not in ubiqutiyDB (doMount)", func() { fakeClient.GetVolumeReturns(resources.Volume{}, fmt.Errorf("error not found in DB")) - mountRequest := k8sresources.FlexVolumeMountRequest{MountPath: "/pod/pv1", MountDevice: "pv1", Opts: map[string]string{}} + mountRequest := k8sresources.FlexVolumeMountRequest{MountPath: mountPoint, MountDevice: "pv1", Opts: map[string]string{}} mountResponse := controller.Mount(mountRequest) @@ -141,7 +152,7 @@ var _ = Describe("Controller", func() { fakeClient.GetVolumeReturns(resources.Volume{Name: "pv1", Backend: "XXX", Mountpoint: "fake"}, nil) fakeMounterFactory.GetMounterPerBackendReturns(fakeMounter, fmt.Errorf(errstr)) controller = ctl.NewControllerWithClient(testLogger, ubiquityConfig, fakeClient, fakeExec, fakeMounterFactory) - mountRequest := k8sresources.FlexVolumeMountRequest{MountPath: "/pod/pv1", MountDevice: "pv1", Opts: map[string]string{}} + mountRequest := k8sresources.FlexVolumeMountRequest{MountPath: mountPoint, MountDevice: "pv1", Opts: map[string]string{}} mountResponse := controller.Mount(mountRequest) @@ -204,7 +215,7 @@ var _ = Describe("Controller", func() { fakeMounter.MountReturns("fake device", fmt.Errorf(errstr)) fakeMounterFactory.GetMounterPerBackendReturns(fakeMounter, nil) controller = ctl.NewControllerWithClient(testLogger, ubiquityConfig, fakeClient, fakeExec, fakeMounterFactory) - mountRequest := k8sresources.FlexVolumeMountRequest{MountPath: "/pod/pv1", MountDevice: "pv1", Opts: map[string]string{"Wwn": "fake"}} + mountRequest := k8sresources.FlexVolumeMountRequest{MountPath: mountPoint, MountDevice: "pv1", Opts: map[string]string{"Wwn": "fake"}} mountResponse := controller.Mount(mountRequest) @@ -226,7 +237,7 @@ var _ = Describe("Controller", func() { controller = ctl.NewControllerWithClient(testLogger, ubiquityConfig, fakeClient, fakeExec, fakeMounterFactory) fakeExec.LstatReturns(nil, errstrObj) fakeExec.IsNotExistReturns(false) - mountRequest := k8sresources.FlexVolumeMountRequest{MountPath: "/pod/pv1", MountDevice: "pv1", Opts: map[string]string{"Wwn": "fake"}, Version: k8sresources.KubernetesVersion_1_6OrLater} + mountRequest := k8sresources.FlexVolumeMountRequest{MountPath: mountPoint, MountDevice: "pv1", Opts: map[string]string{"Wwn": "fake"}, Version: k8sresources.KubernetesVersion_1_6OrLater} mountResponse := controller.Mount(mountRequest) @@ -252,7 +263,7 @@ var _ = Describe("Controller", func() { fakeExec.LstatReturns(nil, errstrObj) fakeExec.IsNotExistReturns(true) fakeExec.SymlinkReturns(errstrObj) - mountRequest := k8sresources.FlexVolumeMountRequest{MountPath: "/pod/pv1", MountDevice: "pv1", Opts: map[string]string{"Wwn": "fake"}, Version: k8sresources.KubernetesVersion_1_6OrLater} + mountRequest := k8sresources.FlexVolumeMountRequest{MountPath: mountPoint, MountDevice: "pv1", Opts: map[string]string{"Wwn": "fake"}, Version: k8sresources.KubernetesVersion_1_6OrLater} mountResponse := controller.Mount(mountRequest) @@ -279,7 +290,7 @@ var _ = Describe("Controller", func() { fakeExec.LstatReturns(nil, errstrObj) fakeExec.IsNotExistReturns(true) fakeExec.SymlinkReturns(nil) - mountRequest := k8sresources.FlexVolumeMountRequest{MountPath: "/pod/pv1", MountDevice: "pv1", Opts: map[string]string{"Wwn": "fake"}, Version: k8sresources.KubernetesVersion_1_6OrLater} + mountRequest := k8sresources.FlexVolumeMountRequest{MountPath: mountPoint, MountDevice: "pv1", Opts: map[string]string{"Wwn": "fake"}, Version: k8sresources.KubernetesVersion_1_6OrLater} mountResponse := controller.Mount(mountRequest) @@ -303,7 +314,7 @@ var _ = Describe("Controller", func() { fakeMounter.MountReturns("/ubiquity/wwn1", nil) fakeMounterFactory.GetMounterPerBackendReturns(fakeMounter, nil) controller = ctl.NewControllerWithClient(testLogger, ubiquityConfig, fakeClient, fakeExec, fakeMounterFactory) - mountRequest := k8sresources.FlexVolumeMountRequest{MountPath: "/tmp", MountDevice: "pv1", Opts: map[string]string{"Wwn": "fake"}, Version: k8sresources.KubernetesVersion_1_6OrLater} + mountRequest := k8sresources.FlexVolumeMountRequest{MountPath: mountPoint, MountDevice: "pv1", Opts: map[string]string{"Wwn": "fake"}, Version: k8sresources.KubernetesVersion_1_6OrLater} fakeExec.LstatReturns(nil, nil) fakeExec.IsDirReturns(true) fakeExec.RemoveReturns(errstrObj) @@ -330,7 +341,7 @@ var _ = Describe("Controller", func() { fakeMounter.MountReturns("/ubiquity/wwn1", nil) fakeMounterFactory.GetMounterPerBackendReturns(fakeMounter, nil) controller = ctl.NewControllerWithClient(testLogger, ubiquityConfig, fakeClient, fakeExec, fakeMounterFactory) - mountRequest := k8sresources.FlexVolumeMountRequest{MountPath: "/tmp", MountDevice: "pv1", Opts: map[string]string{"Wwn": "fake"}, Version: k8sresources.KubernetesVersion_1_6OrLater} + mountRequest := k8sresources.FlexVolumeMountRequest{MountPath: mountPoint, MountDevice: "pv1", Opts: map[string]string{"Wwn": "fake"}, Version: k8sresources.KubernetesVersion_1_6OrLater} fakeExec.LstatReturns(nil, nil) fakeExec.IsDirReturns(true) fakeExec.RemoveReturns(nil) @@ -357,7 +368,7 @@ var _ = Describe("Controller", func() { fakeMounter.MountReturns("/ubiquity/wwn1", nil) fakeMounterFactory.GetMounterPerBackendReturns(fakeMounter, nil) controller = ctl.NewControllerWithClient(testLogger, ubiquityConfig, fakeClient, fakeExec, fakeMounterFactory) - mountRequest := k8sresources.FlexVolumeMountRequest{MountPath: "/tmp", MountDevice: "pv1", Opts: map[string]string{"Wwn": "fake"}, Version: k8sresources.KubernetesVersion_1_6OrLater} + mountRequest := k8sresources.FlexVolumeMountRequest{MountPath: mountPoint, MountDevice: "pv1", Opts: map[string]string{"Wwn": "fake"}, Version: k8sresources.KubernetesVersion_1_6OrLater} fakeExec.LstatReturns(nil, nil) fakeExec.IsDirReturns(true) fakeExec.RemoveReturns(nil) @@ -387,7 +398,7 @@ var _ = Describe("Controller", func() { fakeMounter.MountReturns("/ubiquity/wwn1", nil) fakeMounterFactory.GetMounterPerBackendReturns(fakeMounter, nil) controller = ctl.NewControllerWithClient(testLogger, ubiquityConfig, fakeClient, fakeExec, fakeMounterFactory) - mountRequest := k8sresources.FlexVolumeMountRequest{MountPath: "/tmp", MountDevice: "pv1", Opts: map[string]string{"Wwn": "fake"}, Version: k8sresources.KubernetesVersion_1_6OrLater} + mountRequest := k8sresources.FlexVolumeMountRequest{MountPath: mountPoint, MountDevice: "pv1", Opts: map[string]string{"Wwn": "fake"}, Version: k8sresources.KubernetesVersion_1_6OrLater} fakeExec.LstatReturns(nil, nil) fakeExec.IsDirReturns(false) fakeExec.IsSlinkReturns(true) @@ -414,7 +425,7 @@ var _ = Describe("Controller", func() { fakeMounter.MountReturns(mountPath, nil) fakeMounterFactory.GetMounterPerBackendReturns(fakeMounter, nil) controller = ctl.NewControllerWithClient(testLogger, ubiquityConfig, fakeClient, fakeExec, fakeMounterFactory) - mountRequest := k8sresources.FlexVolumeMountRequest{MountPath: "/pod/pv1", MountDevice: "pv1", Opts: map[string]string{"Wwn": "fake"}, Version: k8sresources.KubernetesVersion_1_6OrLater} + mountRequest := k8sresources.FlexVolumeMountRequest{MountPath: mountPoint, MountDevice: "pv1", Opts: map[string]string{"Wwn": "fake"}, Version: k8sresources.KubernetesVersion_1_6OrLater} fakeExec.LstatReturns(nil, nil) fakeExec.IsDirReturns(false) fakeExec.IsSlinkReturns(true) @@ -443,7 +454,7 @@ var _ = Describe("Controller", func() { fakeMounter.MountReturns(mountPath, nil) fakeMounterFactory.GetMounterPerBackendReturns(fakeMounter, nil) controller = ctl.NewControllerWithClient(testLogger, ubiquityConfig, fakeClient, fakeExec, fakeMounterFactory) - mountRequest := k8sresources.FlexVolumeMountRequest{MountPath: "/pod/pv1", MountDevice: "pv1", Opts: map[string]string{"Wwn": "fake"}, Version: k8sresources.KubernetesVersion_1_6OrLater} + mountRequest := k8sresources.FlexVolumeMountRequest{MountPath: mountPoint, MountDevice: "pv1", Opts: map[string]string{"Wwn": "fake"}, Version: k8sresources.KubernetesVersion_1_6OrLater} fakeExec.LstatReturns(nil, nil) fakeExec.IsDirReturns(false) fakeExec.IsSlinkReturns(true) @@ -471,7 +482,7 @@ var _ = Describe("Controller", func() { fakeMounter.MountReturns(mountPath, nil) fakeMounterFactory.GetMounterPerBackendReturns(fakeMounter, nil) controller = ctl.NewControllerWithClient(testLogger, ubiquityConfig, fakeClient, fakeExec, fakeMounterFactory) - mountRequest := k8sresources.FlexVolumeMountRequest{MountPath: "/pod/pv1", MountDevice: "pv1", Opts: map[string]string{"Wwn": "fake"}, Version: k8sresources.KubernetesVersion_1_6OrLater} + mountRequest := k8sresources.FlexVolumeMountRequest{MountPath: mountPoint, MountDevice: "pv1", Opts: map[string]string{"Wwn": "fake"}, Version: k8sresources.KubernetesVersion_1_6OrLater} fakeExec.LstatReturns(nil, nil) fakeExec.IsDirReturns(false) fakeExec.IsSlinkReturns(false) @@ -489,7 +500,17 @@ var _ = Describe("Controller", func() { Expect(mountResponse.Message).To(MatchRegexp(ctl.K8sPVDirectoryIsNotDirNorSlinkErrorStr)) Expect(mountResponse.Status).To(Equal(ctl.FlexFailureStr)) }) + It("should fail to Mount when there are errors from checking other slinks (idempotent) (doMount)", func() { + err := fmt.Errorf("an Error has occured") + fakeExec.GetGlobFilesReturns(nil, err) + controller = ctl.NewControllerWithClient(testLogger, ubiquityConfig, fakeClient, fakeExec, fakeMounterFactory) + mountRequest := k8sresources.FlexVolumeMountRequest{MountPath: mountPoint, MountDevice: "pv1", Opts: map[string]string{"Wwn": "fake"}, Version: k8sresources.KubernetesVersion_1_6OrLater} + mountResponse := controller.Mount(mountRequest) + Expect(mountResponse.Message).To(Equal(err.Error())) + Expect(mountResponse.Status).To(Equal(ctl.FlexFailureStr)) + Expect(fakeExec.GetGlobFilesCallCount()).To(Equal(1)) + }) }) Context(".Unmount", func() { It("should fail in GetVolume returns error that is not about volume not found in DB (Unmount)", func() { diff --git a/controller/errors.go b/controller/errors.go index c7c69d003..671884900 100644 --- a/controller/errors.go +++ b/controller/errors.go @@ -112,3 +112,25 @@ type BackendNotImplementedGetRealMountpointError struct { func (e *BackendNotImplementedGetRealMountpointError) Error() string { return fmt.Sprintf(BackendNotImplementedGetRealMountpointErrorStr+" backend=[%s]", e.Backend) } + +const PVIsAlreadyUsedByAnotherPodMessage = "PV is already in use by another pod and has an existing slink to mountpoint." + +type PVIsAlreadyUsedByAnotherPod struct { + mountpoint string + slink []string +} + +func (e *PVIsAlreadyUsedByAnotherPod) Error() string { + return fmt.Sprintf(PVIsAlreadyUsedByAnotherPodMessage + " mountpoint=[%s], slinks=[%s]", e.mountpoint, e.slink) +} + +var WrongK8sDirectoryPathErrorMessage = fmt.Sprintf("Expected to find [%s] directory in k8s mount path.",K8sPodsDirecotryName) + +type WrongK8sDirectoryPathError struct { + k8smountdir string +} + +func (e *WrongK8sDirectoryPathError) Error() string { + return fmt.Sprintf(PVIsAlreadyUsedByAnotherPodMessage + "k8smountdir=[%s]", e.k8smountdir) +} + diff --git a/glide.yaml b/glide.yaml index 89bedab90..4b78ef567 100644 --- a/glide.yaml +++ b/glide.yaml @@ -89,7 +89,7 @@ import: subpackages: - lib - package: github.com/IBM/ubiquity - version: 7611848ebb777a726ab2ad2ad78617bf1c0c6331 + version: f9e824946f22b43b0c0d4b160080c3bac94fe716 subpackages: - remote - resources From 05ec3373d483d79cf87212d853227623ebbb99e6 Mon Sep 17 00:00:00 2001 From: Ran Harel Date: Wed, 8 Aug 2018 18:10:59 +0300 Subject: [PATCH 27/40] Updated the glide file to hold fixed commit hashes --- glide.yaml | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/glide.yaml b/glide.yaml index 89bedab90..71a7448f1 100644 --- a/glide.yaml +++ b/glide.yaml @@ -7,6 +7,7 @@ import: - package: github.com/ghodss/yaml version: 73d445a93680fa1a78ae23a5839bad48f32ba1ee - package: github.com/go-openapi/spec + version: 384415f06ee238aae1df5caad877de6ceac3a5c4 - package: github.com/gogo/protobuf version: c0656edd0d9eab7c66d1eb0c568f9039345796f7 subpackages: @@ -14,10 +15,13 @@ import: - sortkeys - ptypes - package: github.com/golang/glog + version: 23def4e6c14b4da8ac2ed8007337bc5eb5007998 - package: github.com/golang/groupcache + version: 24b0969c4cb722950103eed87108c8d291a8df00 subpackages: - lru - package: github.com/google/gofuzz + version: 24818f796faf91cd76ec7bddd72458fbced7a6c1 - package: github.com/googleapis/gnostic version: 0c5108395e2debce0d731cf0287ddf7242066aba subpackages: @@ -25,10 +29,13 @@ import: - package: github.com/gorilla/mux version: v1.5.0 - package: github.com/gregjones/httpcache + version: 9cad4c3443a7200dd6400aef47183728de563a38 subpackages: - diskcache - package: github.com/hashicorp/golang-lru + version: 0fb14efe8c47ae851c0034ed7a448854d3d34cf3 - package: github.com/howeyc/gopass + version: bf9dde6d0d2c004a008c27aaee91170c786f6db8 - package: github.com/imdario/mergo version: 6633656539c1639d9d78127b7d47c622b5d7b6dc - package: github.com/jinzhu/gorm @@ -48,30 +55,44 @@ import: - package: github.com/spf13/pflag version: 5ccb023bc27df288a957c5e994cd44fd19619465 - package: k8s.io/kube-openapi + version: e3762e86a74c878ffed47484592986685639c2cd subpackages: - pkg/common - pkg/util/proto - package: golang.org/x/net + version: f4c29de78a2a91c00474a2e689954305c350adf9 - package: github.com/jinzhu/inflection + version: 04140366298a54a039076d798123ffa108fff46c - package: github.com/gorilla/context version: v1.1.1 - package: github.com/go-openapi/jsonpointer + version: 0.15.0 - package: github.com/go-openapi/jsonreference + version: 0.15.0 - package: github.com/go-openapi/swag + version: 0.15.0 - package: gopkg.in/inf.v0 + version: d2d2541c53f18d2a059457998ce2876cc8e67cbf - package: github.com/emicklei/go-restful version: ff4f55a206334ef123e4f79bbf348980da81ca46 - package: golang.org/x/crypto + version: 56440b844dfe139a8ac053f4ecac0b20b79058f4 - package: golang.org/x/sys + version: 34b17bdb430002e9db9ae7ddc8480b9fa05edc22 - package: github.com/PuerkitoBio/purell version: 8a290539e2e8629dbc4e6bad948158f790ec31f4 - package: github.com/mailru/easyjson + version: 03f2033d19d5860aef995fe360ac7d395cd8ce65 - package: gopkg.in/yaml.v2 version: 53feefa2559fb8dfa8d81baad31be332c97d6c77 - package: golang.org/x/text + version: cb6730876b985e110843c1842a7a63a63677cf08 - package: github.com/google/btree + version: e89373fe6b4a7413d7acd6da1725b83ef713e6e4 - package: github.com/lib/pq + version: 90697d60dd844d5ef6ff15135d0203f65d2f53b8 - package: github.com/PuerkitoBio/urlesc + version: de5bf2ad457846296e2031421a34e2568e304e35 - package: github.com/modern-go/concurrent version: 1.0.3 - package: github.com/modern-go/reflect2 From 80649f73d3f784d642223c1df011fe1721e0b1c2 Mon Sep 17 00:00:00 2001 From: olgashtivelman <33713489+olgashtivelman@users.noreply.github.com> Date: Thu, 9 Aug 2018 11:44:05 +0300 Subject: [PATCH 28/40] Fix/ub 1449 should not fail unmount when slink is broken (#205) This PR will allow the flex to continue with the unmount process even if the link from k8smointpath (/var/lib/kubelet/pods/a0929255-9b1a-11e8-9b44-005056a4d4cb/volumes/ibm~ubiquity-k8s-flex/pvc-ab512cc6-9b0f-11e8-9b44-005056a4d4cb) to the mountpoint (/ubiquity/WWN) is broken and the mountpoint does not exist. --- controller/controller.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/controller/controller.go b/controller/controller.go index 4c2f3b9af..2c2254ec6 100644 --- a/controller/controller.go +++ b/controller/controller.go @@ -355,7 +355,12 @@ func (c *Controller) checkSlinkBeforeUmount(k8sPVDirectoryPath string, realMount // Its already slink so check if slink is ok and skip else raise error evalSlink, err := c.exec.EvalSymlinks(k8sPVDirectoryPath) if err != nil { - return true, c.logger.ErrorRet(err, "Controller: Idempotent - failed eval the slink of PV directory(k8s-mountpoint)", logs.Args{{"k8s-mountpoint", k8sPVDirectoryPath}}) + message := "Controller: Idempotent - failed to eval the slink of the PV directory(k8s-mountpoint)" + if os.IsNotExist(err){ + c.logger.Warning(message, logs.Args{{"k8s-mountpoint", k8sPVDirectoryPath},{"error" , err}}) + return true, nil + } + return true, c.logger.ErrorRet(err, message, logs.Args{{"k8s-mountpoint", k8sPVDirectoryPath}}) } if evalSlink == realMountedPath { c.logger.Info("PV directory(k8s-mountpoint) is slink that point to the right mountpoint.", logs.Args{{"k8s-mountpoint", k8sPVDirectoryPath}, {"mountpoint", realMountedPath}}) From 1539a86472696a5b836f6c60d05e6ab11564726d Mon Sep 17 00:00:00 2001 From: Olga Shtivelman Date: Mon, 13 Aug 2018 17:47:54 +0300 Subject: [PATCH 29/40] UB-1474: change glide# - added idempotent message to the log --- glide.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/glide.yaml b/glide.yaml index bfe65840e..4c6e2b30d 100644 --- a/glide.yaml +++ b/glide.yaml @@ -110,7 +110,7 @@ import: subpackages: - lib - package: github.com/IBM/ubiquity - version: f9e824946f22b43b0c0d4b160080c3bac94fe716 + version: 525b20c3b6bfd66f7839b0d436df522df5f40bce subpackages: - remote - resources From d220f7204ac0329862e0e89b725c5e39932f896e Mon Sep 17 00:00:00 2001 From: Isaac Beckman Date: Thu, 16 Aug 2018 15:40:43 +0300 Subject: [PATCH 30/40] Align ubiquity-k8s with ubiquity latest commit --- glide.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/glide.yaml b/glide.yaml index 4c6e2b30d..c675c8377 100644 --- a/glide.yaml +++ b/glide.yaml @@ -110,7 +110,7 @@ import: subpackages: - lib - package: github.com/IBM/ubiquity - version: 525b20c3b6bfd66f7839b0d436df522df5f40bce + version: dacf163310a759509fb2658f3c7fddeae5ba00a8 subpackages: - remote - resources From 8658088037a13b6ca98a795fb014c009e37afbdf Mon Sep 17 00:00:00 2001 From: Isaac Beckman Date: Thu, 16 Aug 2018 16:48:04 +0300 Subject: [PATCH 31/40] Resolve conflicts in glide --- glide.yaml | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/glide.yaml b/glide.yaml index c675c8377..bd7cc3993 100644 --- a/glide.yaml +++ b/glide.yaml @@ -7,7 +7,7 @@ import: - package: github.com/ghodss/yaml version: 73d445a93680fa1a78ae23a5839bad48f32ba1ee - package: github.com/go-openapi/spec - version: 384415f06ee238aae1df5caad877de6ceac3a5c4 + version: 7abd5745472fff5eb3685386d5fb8bf38683154d - package: github.com/gogo/protobuf version: c0656edd0d9eab7c66d1eb0c568f9039345796f7 subpackages: @@ -17,11 +17,11 @@ import: - package: github.com/golang/glog version: 23def4e6c14b4da8ac2ed8007337bc5eb5007998 - package: github.com/golang/groupcache - version: 24b0969c4cb722950103eed87108c8d291a8df00 + version: 02826c3e79038b59d737d3b1c0a1d937f71a4433 subpackages: - lru - package: github.com/google/gofuzz - version: 24818f796faf91cd76ec7bddd72458fbced7a6c1 + version: 44d81051d367757e1c7c6a5a86423ece9afcf63c - package: github.com/googleapis/gnostic version: 0c5108395e2debce0d731cf0287ddf7242066aba subpackages: @@ -29,11 +29,11 @@ import: - package: github.com/gorilla/mux version: v1.5.0 - package: github.com/gregjones/httpcache - version: 9cad4c3443a7200dd6400aef47183728de563a38 + version: 787624de3eb7bd915c329cba748687a3b22666a6 subpackages: - diskcache - package: github.com/hashicorp/golang-lru - version: 0fb14efe8c47ae851c0034ed7a448854d3d34cf3 + version: a0d98a5f288019575c6d1f4bb1573fef2d1fcdc4 - package: github.com/howeyc/gopass version: bf9dde6d0d2c004a008c27aaee91170c786f6db8 - package: github.com/imdario/mergo @@ -55,44 +55,44 @@ import: - package: github.com/spf13/pflag version: 5ccb023bc27df288a957c5e994cd44fd19619465 - package: k8s.io/kube-openapi - version: e3762e86a74c878ffed47484592986685639c2cd + version: 39a7bf85c140f972372c2a0d1ee40adbf0c8bfe1 subpackages: - pkg/common - pkg/util/proto - package: golang.org/x/net - version: f4c29de78a2a91c00474a2e689954305c350adf9 + version: 1c05540f6879653db88113bc4a2b70aec4bd491f - package: github.com/jinzhu/inflection version: 04140366298a54a039076d798123ffa108fff46c - package: github.com/gorilla/context version: v1.1.1 - package: github.com/go-openapi/jsonpointer - version: 0.15.0 + version: 46af16f9f7b149af66e5d1bd010e3574dc06de98 - package: github.com/go-openapi/jsonreference - version: 0.15.0 + version: 13c6e3589ad90f49bd3e3bbe2c2cb3d7a4142272 - package: github.com/go-openapi/swag - version: 0.15.0 + version: f3f9494671f93fcff853e3c6e9e948b3eb71e590 - package: gopkg.in/inf.v0 - version: d2d2541c53f18d2a059457998ce2876cc8e67cbf + version: 3887ee99ecf07df5b447e9b00d9c0b2adaa9f3e4 - package: github.com/emicklei/go-restful version: ff4f55a206334ef123e4f79bbf348980da81ca46 - package: golang.org/x/crypto - version: 56440b844dfe139a8ac053f4ecac0b20b79058f4 + version: 81e90905daefcd6fd217b62423c0908922eadb30 - package: golang.org/x/sys version: 34b17bdb430002e9db9ae7ddc8480b9fa05edc22 - package: github.com/PuerkitoBio/purell version: 8a290539e2e8629dbc4e6bad948158f790ec31f4 - package: github.com/mailru/easyjson - version: 03f2033d19d5860aef995fe360ac7d395cd8ce65 + version: 2f5df55504ebc322e4d52d34df6a1f5b503bf26d - package: gopkg.in/yaml.v2 version: 53feefa2559fb8dfa8d81baad31be332c97d6c77 - package: golang.org/x/text - version: cb6730876b985e110843c1842a7a63a63677cf08 + version: b19bf474d317b857955b12035d2c5acb57ce8b01 - package: github.com/google/btree - version: e89373fe6b4a7413d7acd6da1725b83ef713e6e4 + version: 7d79101e329e5a3adf994758c578dab82b90c017 - package: github.com/lib/pq version: 90697d60dd844d5ef6ff15135d0203f65d2f53b8 - package: github.com/PuerkitoBio/urlesc - version: de5bf2ad457846296e2031421a34e2568e304e35 + version: 5bd2802263f21d8788851d5305584c82a5c75d7e - package: github.com/modern-go/concurrent version: 1.0.3 - package: github.com/modern-go/reflect2 From d0238215fd919235839fd6920327fe489c1b5b94 Mon Sep 17 00:00:00 2001 From: Isaac Beckman Date: Thu, 16 Aug 2018 17:05:54 +0300 Subject: [PATCH 32/40] Align glide on golang.org/x/sys --- glide.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/glide.yaml b/glide.yaml index bd7cc3993..868cad9d0 100644 --- a/glide.yaml +++ b/glide.yaml @@ -78,7 +78,7 @@ import: - package: golang.org/x/crypto version: 81e90905daefcd6fd217b62423c0908922eadb30 - package: golang.org/x/sys - version: 34b17bdb430002e9db9ae7ddc8480b9fa05edc22 + version: a2e06a18 - package: github.com/PuerkitoBio/purell version: 8a290539e2e8629dbc4e6bad948158f790ec31f4 - package: github.com/mailru/easyjson From 9bb3f5c4d554888a652675432a3c407b569fed48 Mon Sep 17 00:00:00 2001 From: Isaac Beckman Date: Sun, 19 Aug 2018 14:53:35 +0300 Subject: [PATCH 33/40] Align ubiquity-k8s with ubiquity latest commit --- glide.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/glide.yaml b/glide.yaml index c675c8377..c996a9d84 100644 --- a/glide.yaml +++ b/glide.yaml @@ -110,7 +110,7 @@ import: subpackages: - lib - package: github.com/IBM/ubiquity - version: dacf163310a759509fb2658f3c7fddeae5ba00a8 + version: 17e3da6c00de6aec681f27e5d69c5b50328fcdaa subpackages: - remote - resources From dd7b8b411f4819f008adf04179b8e81287470740 Mon Sep 17 00:00:00 2001 From: Olga Shtivelman Date: Sun, 19 Aug 2018 16:28:21 +0300 Subject: [PATCH 34/40] UB-1475: returning the actual error from the Discover instead of masking it as Volume not found (#236) --- glide.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/glide.yaml b/glide.yaml index 1d9538563..23c7af206 100644 --- a/glide.yaml +++ b/glide.yaml @@ -110,7 +110,7 @@ import: subpackages: - lib - package: github.com/IBM/ubiquity - version: 17e3da6c00de6aec681f27e5d69c5b50328fcdaa + version: 382fc6e1cff9874a86702fc265ff97ac9a4388d8 subpackages: - remote - resources From 1f242210bba5824b13d638039f3d85fbf568914b Mon Sep 17 00:00:00 2001 From: Olga Shtivelman Date: Thu, 23 Aug 2018 15:21:59 +0300 Subject: [PATCH 35/40] UB-1407: added timeouts to umount commands --- glide.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/glide.yaml b/glide.yaml index 23c7af206..977f2897a 100644 --- a/glide.yaml +++ b/glide.yaml @@ -110,7 +110,7 @@ import: subpackages: - lib - package: github.com/IBM/ubiquity - version: 382fc6e1cff9874a86702fc265ff97ac9a4388d8 + version: 01b687168ce391d7066bf487e3dd57afbbc4c5bf subpackages: - remote - resources From 234e4f72670f47dce52b3162af106ff7d1f02520 Mon Sep 17 00:00:00 2001 From: Olga Shtivelman Date: Thu, 23 Aug 2018 16:51:54 +0300 Subject: [PATCH 36/40] UB-1474: added log message for idempotent issue --- glide.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/glide.yaml b/glide.yaml index 977f2897a..858ce09b1 100644 --- a/glide.yaml +++ b/glide.yaml @@ -110,7 +110,7 @@ import: subpackages: - lib - package: github.com/IBM/ubiquity - version: 01b687168ce391d7066bf487e3dd57afbbc4c5bf + version: 6162da482b93d21513f727f83173330897fa1b52 subpackages: - remote - resources From a89181ac44d2eb2985117a601f08dc0cb3e7cbff Mon Sep 17 00:00:00 2001 From: Olga Shtivelman Date: Mon, 27 Aug 2018 15:38:14 +0300 Subject: [PATCH 37/40] ub-1436: umount when pv does not exist fix --- glide.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/glide.yaml b/glide.yaml index 858ce09b1..285519a84 100644 --- a/glide.yaml +++ b/glide.yaml @@ -110,7 +110,7 @@ import: subpackages: - lib - package: github.com/IBM/ubiquity - version: 6162da482b93d21513f727f83173330897fa1b52 + version: 740b73b455ba0152f47af6b8c2c36b4965d5b1ba subpackages: - remote - resources From 89b621cbe83d71a3263d90b0aba5fdbd0dc45094 Mon Sep 17 00:00:00 2001 From: shay-berman Date: Mon, 27 Aug 2018 17:34:25 +0300 Subject: [PATCH 38/40] Add contribution-guide.md for build and testing (#189) --- contribution-guide.md | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 contribution-guide.md diff --git a/contribution-guide.md b/contribution-guide.md new file mode 100644 index 000000000..cb4214f55 --- /dev/null +++ b/contribution-guide.md @@ -0,0 +1,40 @@ +# Contribution guide +The Ubiquity team accepts contributions from IBM employees using GitHub pull requests. +Pushing to master is not allowed. Any direct push to master might interfere with our CI process. + +If you want to make a change, create your own branch out of `dev` branch, make your changes. Once you are done, submit a pull request to the `dev` branch. When accepted, the changes will make their way into `master` after we merge. + +Verify your changes before submitting a pull request by running the unit, integration and acceptance tests. See the testing section for details. In addition, make sure that your changes are covered by existing or new unit testing. + +# Build prerequisites + * Install [golang](https://golang.org/) (>=1.9.1). + * Install [git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git). + * Install gcc. + * Configure go. GOPATH environment variable must be set correctly before starting the build process. Create a new directory and set it as GOPATH. + +### Download and build source code +* Configure ssh-keys for github.com. go tools require passwordless ssh access to github. If you have not set up ssh keys for your github profile, follow these [instructions](https://help.github.com/enterprise/2.7/user/articles/generating-an-ssh-key/) before you proceed. +* Build Ubiquity Provisioner and FlexVolume from source. +```bash +mkdir -p $HOME/workspace +export GOPATH=$HOME/workspace +mkdir -p $GOPATH/src/github.com/IBM +cd $GOPATH/src/github.com/IBM +git clone git@github.com:IBM/ubiquity-k8s.git +cd ubiquity-k8s +./scripts/run_glide_up +./scripts/build_provisioner +./scripts/build_flex_driver +``` +# Testing Ubiquity Provisioner and FlexVolume + +Run the tests: +```bash +./scripts/run_glide_up +./scripts/run_units.sh +``` + +# Squash and merge + +Upon the merge (by either you or your reviewer), all commits on the review branch must represent meaningful milestones or units of work. Use commit message to detail the development and review process. +Before merging a PR, squash any fix review feedback, typo, and rebased sorts of commits. From c4501eac028fe7402925656f9f167095bad3a5e9 Mon Sep 17 00:00:00 2001 From: shay-berman Date: Tue, 28 Aug 2018 12:10:29 +0300 Subject: [PATCH 39/40] Update notices file for version 1.2 and update ubiquity_installer.conf image versions (#207) * Update notices file for version 1.2 * ubiquity_installer.conf : update the image version 1.1.1 -> 1.2.0 --- glide.yaml | 2 +- .../ubiquity_installer.conf | 8 +- ...ile_for_ibm_storage_enabler_for_containers | 4753 ++++++++++------- 3 files changed, 2815 insertions(+), 1948 deletions(-) diff --git a/glide.yaml b/glide.yaml index 285519a84..1c934f803 100644 --- a/glide.yaml +++ b/glide.yaml @@ -110,7 +110,7 @@ import: subpackages: - lib - package: github.com/IBM/ubiquity - version: 740b73b455ba0152f47af6b8c2c36b4965d5b1ba + version: a91d9984ae76f7a15cb18b5e0c318bc8d85a350e subpackages: - remote - resources diff --git a/scripts/installer-for-ibm-storage-enabler-for-containers/ubiquity_installer.conf b/scripts/installer-for-ibm-storage-enabler-for-containers/ubiquity_installer.conf index be4b27a1c..7a4a34523 100644 --- a/scripts/installer-for-ibm-storage-enabler-for-containers/ubiquity_installer.conf +++ b/scripts/installer-for-ibm-storage-enabler-for-containers/ubiquity_installer.conf @@ -10,10 +10,10 @@ # ---------------------------------------------------- # The Docker images of IBM Storage Enabler for Containers. -UBIQUITY_IMAGE=ibmcom/ibm-storage-enabler-for-containers:1.1.1 -UBIQUITY_DB_IMAGE=ibmcom/ibm-storage-enabler-for-containers-db:1.1.1 -UBIQUITY_K8S_PROVISIONER_IMAGE=ibmcom/ibm-storage-dynamic-provisioner-for-kubernetes:1.1.1 -UBIQUITY_K8S_FLEX_IMAGE=ibmcom/ibm-storage-flex-volume-for-kubernetes:1.1.1 +UBIQUITY_IMAGE=ibmcom/ibm-storage-enabler-for-containers:1.2.0 +UBIQUITY_DB_IMAGE=ibmcom/ibm-storage-enabler-for-containers-db:1.2.0 +UBIQUITY_K8S_PROVISIONER_IMAGE=ibmcom/ibm-storage-dynamic-provisioner-for-kubernetes:1.2.0 +UBIQUITY_K8S_FLEX_IMAGE=ibmcom/ibm-storage-flex-volume-for-kubernetes:1.2.0 # Parameters in ubiquity-configmap.yml that impact on ubiquity deployment #----------------------------------------------------------------- diff --git a/scripts/notices_file_for_ibm_storage_enabler_for_containers b/scripts/notices_file_for_ibm_storage_enabler_for_containers index 74d7a308f..34f4deb9f 100644 --- a/scripts/notices_file_for_ibm_storage_enabler_for_containers +++ b/scripts/notices_file_for_ibm_storage_enabler_for_containers @@ -4,10 +4,10 @@ Additional Software License Agreements and Notices This file details additional Software License Agreements and third party notices and information that are required to be reproduced for the following programs: +IBM Storage Enabler for Containers 1.2 +IBM Storage Kubernetes FlexVolume 1.2 +IBM Storage Kubernetes Dynamic Provisioner 1.2 -IBM Storage Enabler for Containers v1.1.1 -IBM Storage Kubernetes FlexVolume v1.1.1 -IBM Storage Kubernetes Dynamic Provisioner v1.1.1 =========================================================================== Section 1 - TERMS AND CONDITIONS FOR SEPARATELY LICENSED CODE @@ -25,11 +25,15 @@ The following are Separately Licensed Code: alpine-baselayout version 3.0.5 apk-tools version 2.8.2 +CA-certificates 20171114 busybox version 1.27.2 -kubernetes incubator-external-storage version 3.0.0-beta2 -kubernetes version 1.8.0 library +kubernetes incubator-external-storage commit level 92295a3 +kubernetes version 1.9.2 libc-utils version 0.9.33.2 pax-utils version 1.2.2 +ratelimit commit level 5b9ff86 +yaml.v2 commit level 53feefa + @@@@@@@@@@@@ @@ -183,7 +187,7 @@ such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. - + 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an @@ -1045,7 +1049,8 @@ convey the exclusion of warranty; and each file should have at least the You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301 USA Also add information on how to contact you by electronic and paper mail. @@ -1054,7 +1059,8 @@ school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the - library `Frob' (a library for tweaking knobs) written by James Random Hacker. + library `Frob' (a library for tweaking knobs) written + by James Random Hacker. , 1 April 1990 Ty Coon, President of Vice @@ -1070,6 +1076,11 @@ END of GNU LGPL Version 2.1 License +=========================================================================== +Start of Notices for LGPL v2.1 Licensed Codes +=========================================================================== + + =========================================================================== Notices for LIBC-Utils version 0.9.33.2 --------------------------------------------------------------------------- @@ -2390,9 +2401,9 @@ this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp -============================================================================== +=========================================================================== End of Notices for LGPL v2.1 Licensed Codes -============================================================================== +=========================================================================== @@@@@@@@@@@@ @@ -2402,9 +2413,12 @@ GNU LESSER GENERAL PUBLIC LICENSE V3 This Program includes some or all of the following Modifiable Third Party Code that IBM obtained under the GNU Lesser General Public License. -Portions of kubernetes version 1.8.0 library -Portions of kubernetes incubator-external-storage version 3.0.0-beta2 +Portions of kubernetes version 1.9.2 +Portions of kubernetes incubator-external-storage commit level 92295a3 +ratelimit commit level 5b9ff86 +Portions of yaml.v2 commit level 53feefa +--------------------------------------------------------------------------- As a special exception to the GNU Lesser General Public License version 3 ("LGPL3"), the copyright holders of this Library give you permission to @@ -2590,6 +2604,8 @@ apply, that proxy's public statement of acceptance of any version is permanent authorization for you to choose that version for the Library. + + =========================================================================== End GNU Lesser General Public License Version 3 =========================================================================== @@ -2604,7 +2620,7 @@ GNU GENERAL PUBLIC LICENSE V3 --------------------------------------------------------------------------- START of GNU GPL version 3.0 License --------------------------------------------------------------------------- - + GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 @@ -3296,10 +3312,10 @@ alpine-baselayout version 3.0.5 apk-tools version 2.8.2 Portions of CA-certificates 20171114 busybox version 1.27.2 +Portions of kubernetes version 1.9.2 Portions of libc-utils version 0.9.33.2 pax-utils version 1.2.2 - --------------------------------------------------------------------------- START of GNU GPL version 2 License --------------------------------------------------------------------------- @@ -3650,6 +3666,12 @@ END of GNU GPL version 2 License + +=========================================================================== +Start of Notices for GPL v2 Licensed Codes +=========================================================================== + + =========================================================================== Notices for apk-tools version 2.8.2 --------------------------------------------------------------------------- @@ -3851,7 +3873,7 @@ are met: 3. - + 4. Neither the name of the University nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. @@ -4298,27 +4320,30 @@ you can buy me a beer in return. Ned Ludd. --solarx -============================================================================== + +=========================================================================== End of Notices for GPL v2 Licensed Codes -============================================================================== +=========================================================================== @@@@@@@@@@@@ ========================================================================== Offer to obtain source code for GNU GPL and GNU LGPL licensed software -distributed with the IBM Storage Enabler for Containers v1.1.1, IBM -Storage Kubernetes FlexVolume v1.1.1 and IBM Storage Kubernetes Dynamic -Provisioner v1.1.1: +distributed with the IBM Storage Enabler for Containers 1.2, IBM +Storage Kubernetes FlexVolume 1.2 and IBM Storage Kubernetes Dynamic +Provisioner 1.2: alpine-baselayout version 3.0.5 apk-tools version 2.8.2 busybox version 1.27.2 CA-certificates 20171114 -kubernetes incubator-external-storage version 3.0.0-beta2 -kubernetes version 1.8.0 library +kubernetes incubator-external-storage commit level 92295a3 +kubernetes version 1.9.2 libc-utils version 0.9.33.2 pax-utils version 1.2.2 +ratelimit commit level 5b9ff86 +yaml.v2 commit level 53feefa Source code for the above listed licensed software is available upon written request to the following address: @@ -4336,8 +4361,8 @@ END OF Offer for GNU GPL and LGPL Source Code =========================================================================== END OF TERMS AND CONDITIONS FOR SEPARATELY LICENSED CODE for IBM Storage -Enabler for Containers v1.1.1, IBM Storage Kubernetes FlexVolume v1.1.1, -and IBM Storage Kubernetes Dynamic Provisioner v1.1.1 +Enabler for Containers 1.2, IBM Storage Kubernetes FlexVolume 1.2, +and IBM Storage Kubernetes Dynamic Provisioner 1.2 =========================================================================== @@ -4371,11 +4396,23 @@ APACHE 2.0 LICENSED CODE: The Program includes all or portions of the following software which IBM obtained under the terms and conditions of the Apache License Version 2.0: -kubernetes version 1.8 -kubernetes-api version 1.8 -kubernetes-apimachinery version 1.8 -kubernates-client-go version 5.0.0 -kubernetes-incubator-external-storage version 3.0.0-beta2 +btree commit level e89373f +concurrent version 1.0.3 +glog commit level 23def4e +gnostic commit level 0c51083 +gofuzz commit level 44d8105 +groupcache commit level 02826c3 +jsonpointer commit level 46af16f +jsonreference commit level 13c6e35 +kube-openapi commit level 39a7bf8 +kubernetes-client-go version 1.9.2 +kubernetes-incubator-external-storage commit level 92295a3 +kubernetes version 1.9.2 +kubernetes-api version 1.9.2 +kubernetes-apimachinery version 1.9.2 +reflect2 version 1.0.0 +spec commit level 7abd574 +swag commit level f3f9494 --------------------------------------------------------------------------- @@ -4587,7 +4624,91 @@ kubernetes-incubator-external-storage version 3.0.0-beta2 ======================================================================== NOTICE file corresponding to section 4(d) of the Apache License, -Version 2.0, in this case for the kubernetes version 1.8 distribution +Version 2.0, in this case for the +kubernetes-incubator-external-storage commit level 92295a3 distribution +======================================================================== +Docker +Copyright 2012-2016 Docker, Inc. + +This product includes software developed at Docker, Inc. (https://www.docker.com). + +This product contains software (https://github.com/kr/pty) developed +by Keith Rarick, licensed under the MIT License. + +The following is courtesy of our legal counsel: + + +Use and transfer of Docker may be subject to certain restrictions by the +United States and other governments. +It is your responsibility to ensure that your use and/or transfer does not +violate applicable laws. + +For more information, please see https://www.bis.doc.gov + +See also https://www.apache.org/dev/crypto.html and/or seek legal counsel. + +--------------------------------------------------------------------------- + +Prometheus instrumentation library for Go applications +Copyright 2012-2015 The Prometheus Authors + +This product includes software developed at +SoundCloud Ltd. (http://soundcloud.com/). + + +The following components are included in this product: + +perks - a fork of https://github.com/bmizerany/perks +https://github.com/beorn7/perks +Copyright 2013-2015 Blake Mizerany, Björn Rabenstein +See https://github.com/beorn7/perks/blob/master/README.md for license details. + +Go support for Protocol Buffers - Google's data interchange format +http://github.com/golang/protobuf/ +Copyright 2010 The Go Authors +See source code for license details. + +Support for streaming Protocol Buffer messages for the Go language (golang). +https://github.com/matttproud/golang_protobuf_extensions +Copyright 2013 Matt T. Proud +Licensed under the Apache License, Version 2.0 + +--------------------------------------------------------------------------- + +Data model artifacts for Prometheus. +Copyright 2012-2015 The Prometheus Authors + +This product includes software developed at +SoundCloud Ltd. (http://soundcloud.com/). + +--------------------------------------------------------------------------- + +Common libraries shared by Prometheus Go components. +Copyright 2015 The Prometheus Authors + +This product includes software developed at +SoundCloud Ltd. (http://soundcloud.com/). + +--------------------------------------------------------------------------- + +procfs provides functions to retrieve system, kernel and process +metrics from the pseudo-filesystem proc. + +Copyright 2014-2015 The Prometheus Authors + +This product includes software developed at +SoundCloud Ltd. (http://soundcloud.com/). + +--------------------------------------------------------------------------- + +AWS SDK for Go +Copyright 2015 Amazon.com, Inc. or its affiliates. All Rights Reserved. +Copyright 2014-2015 Stripe, Inc. + + +======================================================================== +NOTICE file corresponding to section 4(d) of the Apache License, +Version 2.0, in this case for the kubernetes version 1.9.2 distribution ======================================================================== procfs provides functions to retrieve system, kernel and process metrics from the pseudo-filesystem proc. @@ -4647,7 +4768,8 @@ This product includes software developed at CoreOS, Inc. Docker Copyright 2012-2017 Docker, Inc. -This product includes software developed at Docker, Inc. (https://www.docker.com). +This product includes software developed at Docker, Inc. +(https://www.docker.com). This product contains software (https://github.com/kr/pty) developed by Keith Rarick, licensed under the MIT License. @@ -4671,7 +4793,8 @@ runc Copyright 2012-2015 Docker, Inc. -This product includes software developed at Docker, Inc. (http://www.docker.com). +This product includes software developed at Docker, Inc. +(http://www.docker.com). The following is courtesy of our legal counsel: @@ -4711,86 +4834,7 @@ Support for streaming Protocol Buffer messages for the Go language (golang). https://github.com/matttproud/golang_protobuf_extensions Copyright 2013 Matt T. Proud Licensed under the Apache License, Version 2.0 - - -======================================================================== -NOTICE file corresponding to section 4(d) of the Apache License, -Version 2.0, in this case for the -kubernetes-incubator-external-storage version 3.0.0-beta2 distribution -======================================================================== -procfs provides functions to retrieve system, kernel and process -metrics from the pseudo-filesystem proc. - -Copyright 2014-2015 The Prometheus Authors - -This product includes software developed at -SoundCloud Ltd. (http://soundcloud.com/). - ---------------------------------------------------------------------------- - -Common libraries shared by Prometheus Go components. -Copyright 2015 The Prometheus Authors - -This product includes software developed at -SoundCloud Ltd. (http://soundcloud.com/). - - ---------------------------------------------------------------------------- - -Data model artifacts for Prometheus. -Copyright 2012-2015 The Prometheus Authors - -This product includes software developed at -SoundCloud Ltd. (http://soundcloud.com/). - ---------------------------------------------------------------------------- - -Prometheus instrumentation library for Go applications -Copyright 2012-2015 The Prometheus Authors - -This product includes software developed at -SoundCloud Ltd. (http://soundcloud.com/). - - -The following components are included in this product: - -perks - a fork of https://github.com/bmizerany/perks -https://github.com/beorn7/perks -Copyright 2013-2015 Blake Mizerany, Björn Rabenstein -See https://github.com/beorn7/perks/blob/master/README.md for license details. - -Go support for Protocol Buffers - Google's data interchange format -http://github.com/golang/protobuf/ -Copyright 2010 The Go Authors -See source code for license details. - -Support for streaming Protocol Buffer messages for the Go language (golang). -https://github.com/matttproud/golang_protobuf_extensions -Copyright 2013 Matt T. Proud -Licensed under the Apache License, Version 2.0 - ---------------------------------------------------------------------------- - -Docker -Copyright 2012-2016 Docker, Inc. - -This product includes software developed at Docker, Inc. -(https://www.docker.com). - -This product contains software (https://github.com/kr/pty) developed -by Keith Rarick, licensed under the MIT License. - -The following is courtesy of our legal counsel: - - -Use and transfer of Docker may be subject to certain restrictions by the -United States and other governments. -It is your responsibility to ensure that your use and/or transfer does not -violate applicable laws. - -For more information, please see https://www.bis.doc.gov - -See also https://www.apache.org/dev/crypto.html and/or seek legal counsel. + ===================================================================== END OF APACHE 2.0 NOTICES AND INFORMATION ===================================================================== @@ -4802,15 +4846,10 @@ Start of Notices for Apache 2.0 Licensed Codes =========================================================================== -@@@@@@@@@@@@ =========================================================================== -kubernetes version 1.8: The Program includes kubernetes version 1.8 -software. IBM obtained the kubernetes version 1.8 software under the -terms and conditions of the following license(s): - +Notices for Kubermetes version 1.92 --------------------------------------------------------------------------- - Copyright 2009 The Go Authors. All rights reserved. https://github.com/golang/protobuf Copyright 2010 The Go Authors. All rights reserved. @@ -4893,23 +4932,24 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. Copyright (c) 2014 Steve Francia -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. --------------------------------------------------------------------------- @@ -5022,45 +5062,47 @@ OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Copyright (c) 2015 Microsoft -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. --------------------------------------------------------------------------- Copyright (c) 2015 Frits van Bommel -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. --------------------------------------------------------------------------- @@ -5184,23 +5226,24 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved. -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. --------------------------------------------------------------------------- @@ -5234,26 +5277,29 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. Copyright (c) 2015, Dave Cheney All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: -* Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. +* Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. -* Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. +* Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED +TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. --------------------------------------------------------------------------- @@ -5289,44 +5335,47 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. Copyright (c) 2013 Ben Johnson -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. --------------------------------------------------------------------------- Copyright (c) 2014 Sam Ghods -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. --------------------------------------------------------------------------- @@ -5391,52 +5440,56 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. Copyright (c) 2016, Quobyte Inc. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: -* Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. +* Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. -* Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. +* Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. -* Neither the name of quobyte-automation nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. +* Neither the name of quobyte-automation nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED +TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. --------------------------------------------------------------------------- Copyright (C) 2012 Rob Figueiredo All Rights Reserved. -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. --------------------------------------------------------------------------- @@ -5498,25 +5551,29 @@ opyright ©2013 The gonum Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the + notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - * Neither the name of the gonum project nor the names of its authors and - contributors may be used to endorse or promote products derived from this - software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * Neither the name of the gonum project nor the names of its authors + and contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED +TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. --------------------------------------------------------------------------- @@ -5532,23 +5589,24 @@ modification, are permitted provided that the following conditions are met: this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of the FreeBSD Project. - ---------------------------------------------------------------------------- - +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER +OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation +are those of the authors and should not be interpreted as representing +official policies, either expressed or implied, of the FreeBSD Project. + +--------------------------------------------------------------------------- + Copyright (C) 2013 Blake Mizerany Permission is hereby granted, free of charge, to any person obtaining @@ -5574,23 +5632,24 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Copyright (c) 2014 Benedikt Lang -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. --------------------------------------------------------------------------- @@ -5626,22 +5685,24 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. Copyright (c) 2013 Armon Dadgar -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. --------------------------------------------------------------------------- @@ -5678,45 +5739,47 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. Copyright (c) 2006 Kirill Simonov -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -of the Software, and to permit persons to whom the Software is furnished to do -so, subject to the following conditions: +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. --------------------------------------------------------------------------- Copyright (c) 2014 Joel -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. --------------------------------------------------------------------------- @@ -5791,67 +5854,70 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Copyright (c) 2015 Peter Renström -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. --------------------------------------------------------------------------- Copyright (c) 2014 Simon Eskildsen -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. --------------------------------------------------------------------------- Copyright (c) 2015 Xiang Li -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. --------------------------------------------------------------------------- @@ -5907,45 +5973,47 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Copyright (c) 2016 json-iterator -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. --------------------------------------------------------------------------- Copyright (c) 2015-2017 StorageOS -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. --------------------------------------------------------------------------- @@ -5961,38 +6029,41 @@ this list of conditions and the following disclaimer. this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED +TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. --------------------------------------------------------------------------- Copyright (c) 2014 Stretchr, Inc. -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. --------------------------------------------------------------------------- Copyright (c) 2015 Microsoft Corporation @@ -6053,23 +6124,24 @@ Copyright (c) 2013 The Gorilla WebSocket Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. + Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED +TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. --------------------------------------------------------------------------- @@ -6091,23 +6163,24 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. Copyright (c) 2013 - 2016 Thomas Pelletier, Eric Anderton -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. --------------------------------------------------------------------------- @@ -6158,59 +6231,63 @@ modification, are permitted provided that the following conditions are met: may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER +OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. --------------------------------------------------------------------------- Copyright (c) 2015 Fatih Arslan -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. --------------------------------------------------------------------------- Copyright (c) 2011-2012 Peter Bourgon -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. --------------------------------------------------------------------------- @@ -6248,23 +6325,24 @@ The MIT License (MIT) Copyright (c) 2014 TSUYUSATO Kitsune -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. --------------------------------------------------------------------------- @@ -6300,23 +6378,24 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. Copyright (c) 2014 Jeremy Saenz -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. --------------------------------------------------------------------------- @@ -6347,24 +6426,26 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Copyright (c) 2013-2016 Errplane Inc. -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------- +-------------------------------------------------------------------------- Copyright 2013 Suryandaru Triandana All rights reserved. @@ -6395,23 +6476,24 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. Copyright (c) 2015 Alexander F Rødseth -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. --------------------------------------------------------------------------- @@ -6488,22 +6570,23 @@ All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. +1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER +OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. --------------------------------------------------------------------------- @@ -6575,22 +6658,24 @@ THE SOFTWARE. Copyright (c) 2013 Phillip Bond -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. --------------------------------------------------------------------------- @@ -6634,38 +6719,40 @@ modification, are permitted provided that the following conditions are met: contributors may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED +TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. --------------------------------------------------------------------------- Copyright (c) 2016 David Deng -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. --------------------------------------------------------------------------- @@ -6755,16 +6842,17 @@ modification, are permitted provided that the following conditions are met: this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED +TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. --------------------------------------------------------------------------- @@ -6874,8 +6962,9 @@ THE SOFTWARE. Copyright (c) 2015, Gengo, Inc. All rights reserved. -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. @@ -6888,37 +6977,40 @@ are permitted provided that the following conditions are met: contributors may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER +OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. --------------------------------------------------------------------------- Copyright (c) 2013 Joshua Tacoma -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. --------------------------------------------------------------------------- @@ -6949,108 +7041,96 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Copyright (c) 2016 Yasuhiro Matsumoto -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - - -======================================================================= -END OF kubernetes version 1.8 NOTICES AND INFORMATION -======================================================================= +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. -@@@@@@@@@@@@ -=========================================================================== -kubernetes-incubator-external-storage version 3.0.0-beta2: The -Program includes kubernetes-incubator-external-storage version -3.0.0-beta2 software. IBM obtained the -kubernetes-incubator-external-storage version 3.0.0-beta2 software -under the terms and conditions of the following license(s): - ---------------------------------------------------------------------------- +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -Copyright (c) 2009 The Go Authors. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. +=========================================================================== +Notices for yaml.v2 commit level 53feefa +--------------------------------------------------------------------------- -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +The following files were ported to Go from C files of libyaml, and thus +are still covered by their original copyright and license: ---------------------------------------------------------------------------- + apic.go + emitterc.go + parserc.go + readerc.go + scannerc.go + writerc.go + yamlh.go + yamlprivateh.go -The MIT License (MIT) +Copyright (c) 2006 Kirill Simonov -Copyright (c) 2014 Steve Francia +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. ---------------------------------------------------------------------------- -Copyright (c) 2012 Péter Surányi. Portions Copyright (c) 2009 The Go -Authors. All rights reserved. +Copyright 2009 The Go Authors. All rights reserved. +https://github.com/golang/protobuf +Copyright 2010 The Go Authors. All rights reserved. +https://github.com/golang/protobuf +Copyright 2011 The Go Authors. All rights reserved. +https://github.com/golang/protobuf +Copyright 2012 The Go Authors. All rights reserved. +https://github.com/golang/protobuf +Copyright 2013 The Go Authors. All rights reserved. +https://github.com/golang/protobuf +Copyright 2014 The Go Authors. All rights reserved. +https://github.com/golang/protobuf +Copyright 2015 The Go Authors. All rights reserved. +https://github.com/golang/protobuf +Copyright 2016 The Go Authors. All rights reserved. +https://github.com/golang/protobuf +Copyright 2017 The Go Authors. All rights reserved. +https://github.com/golang/protobuf Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright + * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above + * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - * Neither the name of Google Inc. nor the names of its + * Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. @@ -7068,19 +7148,20 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. --------------------------------------------------------------------------- -Copyright (c) 2012 The Go Authors. All rights reserved. +Copyright 2008 Google Inc. All rights reserved. +https://developers.google.com/protocol-buffers/ Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright + * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above + * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - * Neither the name of Google Inc. nor the names of its + * Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. @@ -7098,107 +7179,49 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. --------------------------------------------------------------------------- -Copyright (c) 2013-2014 Onsi Fakhouri - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ---------------------------------------------------------------------------- - -Copyright (c) 2012 - 2013 Mat Ryer and Tyler Bunnell - -Please consider promoting this project if you find it useful. - -Permission is hereby granted, free of charge, to any person -obtaining a copy of this software and associated documentation -files (the "Software"), to deal in the Software without restriction, -including without limitation the rights to use, copy, modify, merge, -publish, distribute, sublicense, and/or sell copies of the Software, -and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: +Copyright (c) 2013 Dave Collins +Copyright (c) 2015 Dave Collins +Copyright (c) 2013-2015 Dave Collins -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. +Permission to use, copy, modify, and distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT -OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE -OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. --------------------------------------------------------------------------- -Copyright 2016 The Go Authors. All rights reserved. -https://github.com/golang/protobuf +Copyright (c) 2011, Open Knowledge Foundation Ltd. +All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ---------------------------------------------------------------------------- - -Copyright 2011 The Go Authors. All rights reserved. -https://github.com/golang/protobuf + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. + Neither the name of the Open Knowledge Foundation Ltd. nor the + names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY @@ -7208,172 +7231,175 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. --------------------------------------------------------------------------- -Copyright 2012 The Go Authors. All rights reserved. -https://github.com/golang/protobuf +Copyright © 2014 Steve Francia -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. --------------------------------------------------------------------------- -Copyright 2014 The Go Authors. All rights reserved. -https://github.com/golang/protobuf +Copyright (c) 2016 Thomas Pelletier -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. --------------------------------------------------------------------------- -Copyright 2010 The Go Authors. All rights reserved. -https://github.com/golang/protobuf +Copyright (c) 2012 - 2013 Mat Ryer and Tyler Bunnell -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: +Please consider promoting this project if you find it useful. - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. --------------------------------------------------------------------------- -Copyright 2008 Google Inc. All rights reserved. -https://developers.google.com/protocol-buffers/ -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +=========================================================================== +End of Notices for Apache 2.0 Licensed Codes +=========================================================================== + + +@@@@@@@@@@@@ +=========================================================================== +alpine-keys version 2.1: The Program includes alpine-keys version 2.1 +software. IBM obtained the alpine-keys version 2.1 software under the +terms and conditions of the following license(s): --------------------------------------------------------------------------- -Copyright (c) 2013, Dave Cheney -All rights reserved. -Copyright (c) 2015, Dave Cheney -All rights reserved. +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS -IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED -TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A -PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED -TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +======================================================================= +END OF alpine-keys version 2.1 NOTICES AND INFORMATION +======================================================================= + + +@@@@@@@@@@@@ +=========================================================================== +CA-Certificates version 20171114: The Program includes +CA-Certificates version 20171114 software. IBM obtained the +CA-Certificates version 20171114 software under the terms and +conditions of the following license(s): --------------------------------------------------------------------------- -Copyright (c) 2016 Péter Surányi. + Copyright (c) 2013-2014 Timo Teräs + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + +======================================================================= +END OF CA-Certificates version 20171114 NOTICES AND INFORMATION +======================================================================= + + +@@@@@@@@@@@@ +=========================================================================== +context version 1.1.1: The Program includes context version 1.1.1 +software. IBM obtained the context version 1.1.1 software under the +terms and conditions of the following license(s): + +--------------------------------------------------------------------------- + +Copyright (c) 2012 Rodrigo Moraes. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright + * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above + * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT @@ -7387,9 +7413,21 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +======================================================================= +END OF context version 1.1.1 NOTICES AND INFORMATION +======================================================================= + + +@@@@@@@@@@@@ +=========================================================================== +crypto commit level 81e9090: The Program includes crypto commit level +81e9090 software. IBM obtained the crypto commit level 81e9090 +software under the terms and conditions of the following license(s): + --------------------------------------------------------------------------- -Copyright (c) 2011 Google Inc. All rights reserved. +Copyright (c) 2009 The Go Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are @@ -7417,11 +7455,21 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------- -The MIT License (MIT) +======================================================================= +END OF crypto commit level 81e9090 NOTICES AND INFORMATION +======================================================================= -Copyright (c) 2014 Sam Ghods + +@@@@@@@@@@@@ +=========================================================================== +diskv commit level 5f041e8: The Program includes diskv commit level +5f041e8 software. IBM obtained the diskv commit level 5f041e8 +software under the terms and conditions of the following license(s): + +--------------------------------------------------------------------------- + +Copyright (c) 2011-2012 Peter Bourgon Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -7430,88 +7478,117 @@ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. ---------------------------------------------------------------------------- -Copyright (c) 2012 Alex Ogier. All rights reserved. -Copyright (c) 2012 The Go Authors. All rights reserved. +======================================================================= +END OF diskv commit level 5f041e8 NOTICES AND INFORMATION +======================================================================= -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +@@@@@@@@@@@@ +=========================================================================== +easyjson commit level 2f5df55: The Program includes easyjson commit +level 2f5df55 software. IBM obtained the easyjson commit level +2f5df55 software under the terms and conditions of the following license(s): --------------------------------------------------------------------------- -Copyright (C) 2013 Blake Mizerany +Copyright (c) 2016 Mail.Ru Group -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + +======================================================================= +END OF easyjson commit level 2f5df55 NOTICES AND INFORMATION +======================================================================= + + +@@@@@@@@@@@@ +=========================================================================== +go commit level 36b1496: The Program includes go commit level 36b1496 +software. IBM obtained the go commit level 36b1496 software under the +terms and conditions of the following license(s): --------------------------------------------------------------------------- -Copyright (c) 2009,2014 Google Inc. All rights reserved. +MIT License + +Copyright (c) 2016 json-iterator + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + +======================================================================= +END OF go commit level 36b1496 NOTICES AND INFORMATION +======================================================================= + + +@@@@@@@@@@@@ +=========================================================================== +go-flags version 1.4.0: The Program includes go-flags version 1.4.0 +software. IBM obtained the go-flags version 1.4.0 software under the +terms and conditions of the following license(s): + +--------------------------------------------------------------------------- + +Copyright (c) 2012 Jesse van den Kieboom. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. + notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. + copyright notice, this list of conditions and the following disclaimer + in the documentation and/or other materials provided with the + distribution. * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT @@ -7525,10 +7602,21 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +======================================================================= +END OF go-flags version 1.4.0 NOTICES AND INFORMATION +======================================================================= + + +@@@@@@@@@@@@ +=========================================================================== +go-logging version 1: The Program includes go-logging version 1 +software. IBM obtained the go-logging version 1 software under the +terms and conditions of the following license(s): + --------------------------------------------------------------------------- -Copyright (c) 2013 Dario Castañé. All rights reserved. -Copyright (c) 2012 The Go Authors. All rights reserved. +Copyright (c) 2013 Örjan Persson. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are @@ -7556,33 +7644,91 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +======================================================================= +END OF go-logging version 1 NOTICES AND INFORMATION +======================================================================= + + +@@@@@@@@@@@@ +=========================================================================== +go-restful commit level ff4f55a: The Program includes go-restful +commit level ff4f55a software. IBM obtained the go-restful commit +level ff4f55a software under the terms and conditions of the +following license(s): + --------------------------------------------------------------------------- -Copyright (c) 2006 Kirill Simonov +Copyright (c) 2012,2013 Ernest Micklei -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -of the Software, and to permit persons to whom the Software is furnished to do -so, subject to the following conditions: +MIT License -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + +======================================================================= +END OF go-restful commit level ff4f55a NOTICES AND INFORMATION +======================================================================= + + +@@@@@@@@@@@@ +=========================================================================== +go-spew commit level 04cdfd4: The Program includes go-spew commit +level 04cdfd4 software. IBM obtained the go-spew commit level 04cdfd4 +software under the terms and conditions of the following license(s): + +--------------------------------------------------------------------------- + +ISC License + +Copyright (c) 2012-2013 Dave Collins + +Permission to use, copy, modify, and distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + +======================================================================= +END OF go-spew commit level 04cdfd4 NOTICES AND INFORMATION +======================================================================= + + +@@@@@@@@@@@@ +=========================================================================== +go-sqlite3 version 1.3.0: The Program includes go-sqlite3 version +1.3.0 software. IBM obtained the go-sqlite3 version 1.3.0 software +under the terms and conditions of the following license(s): --------------------------------------------------------------------------- The MIT License (MIT) -Copyright (c) 2014 Simon Eskildsen +Copyright (c) 2014 Yasuhiro Matsumoto Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -7591,20 +7737,62 @@ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. --------------------------------------------------------------------------- -Copyright (c) 2012-2013 Dave Collins +Copyright 2009-2010 Cybozu Labs, Inc. +Copyright 2011 Kazuho Oku + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY CYBOZU LABS, INC. ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO +EVENT SHALL CYBOZU LABS, INC. OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are +those of the authors and should not be interpreted as representing official +policies, either expressed or implied, of Cybozu Labs, Inc. + +======================================================================= +END OF go-sqlite3 version 1.3.0 NOTICES AND INFORMATION +======================================================================= + + +@@@@@@@@@@@@ +=========================================================================== +gopass commit level bf9dde6: The Program includes gopass commit level +bf9dde6 software. IBM obtained the gopass commit level bf9dde6 +software under the terms and conditions of the following license(s): + +--------------------------------------------------------------------------- + +ISC License + +Copyright (c) 2012 Chris Howey Permission to use, copy, modify, and distribute this software for any purpose with or without fee is hereby granted, provided that the above @@ -7616,134 +7804,95 @@ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ---------------------------------------------------------------------------- -Copyright (c) 2013, Georg Reinke () -All rights reserved. +======================================================================= +END OF gopass commit level bf9dde6 NOTICES AND INFORMATION +======================================================================= -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -1. Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. +@@@@@@@@@@@@ +=========================================================================== +gorm version 1.0: The Program includes gorm version 1.0 software. IBM +obtained the gorm version 1.0 software under the terms and conditions +of the following license(s): -2. Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. +--------------------------------------------------------------------------- -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED -TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +The MIT License (MIT) ---------------------------------------------------------------------------- +Copyright (c) 2013-NOW Jinzhu -Copyright (c) 2016 Mail.Ru Group +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: -Permission is hereby granted, free of charge, to any person obtaining a -copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +======================================================================= +END OF gorm version 1.0 NOTICES AND INFORMATION +======================================================================= + + +@@@@@@@@@@@@ +=========================================================================== +httpcache commit level 787624d: The Program includes httpcache commit +level 787624d software. IBM obtained the httpcache commit level +787624d software under the terms and conditions of the following license(s): --------------------------------------------------------------------------- -Copyright (c) 2012 Dave Grijalva +Copyright © 2012 Greg Jones (greg.jones@gmail.com) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including +“Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to -the following conditions: +the following conditions: The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. +in all copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ---------------------------------------------------------------------------- - -MIT License - -Copyright (c) 2016 json-iterator - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - ---------------------------------------------------------------------------- - -The MIT License (MIT) +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -Copyright (c) 2014 Stretchr, Inc. -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: +======================================================================= +END OF httpcache commit level 787624d NOTICES AND INFORMATION +======================================================================= -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +@@@@@@@@@@@@ +=========================================================================== +inf commit level 3887ee9: The Program includes inf commit level +3887ee9 software. IBM obtained the inf commit level 3887ee9 software +under the terms and conditions of the following license(s): --------------------------------------------------------------------------- -Copyright (c) 2012 The Go Authors. All rights reserved. -Copyright (c) 2012 fsnotify Authors. All rights reserved. +Copyright (c) 2012 Péter Surányi. Portions Copyright (c) 2009 The Go +Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are @@ -7771,654 +7920,93 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------- - -ISC License -Copyright (c) 2012 Chris Howey +======================================================================= +END OF inf commit level 3887ee9 NOTICES AND INFORMATION +======================================================================= -Permission to use, copy, modify, and distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +@@@@@@@@@@@@ +=========================================================================== +inflection commit level 0414036: The Program includes inflection +commit level 0414036 software. IBM obtained the inflection commit +level 0414036 software under the terms and conditions of the +following license(s): --------------------------------------------------------------------------- The MIT License (MIT) -Copyright (c) 2013 - 2016 Thomas Pelletier, Eric Anderton +Copyright (c) 2015 - Jinzhu -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------------------------- -Copyright (c) 2012, Martin Angers -All rights reserved. +======================================================================= +END OF inflection commit level 0414036 NOTICES AND INFORMATION +======================================================================= -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: -* Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. +@@@@@@@@@@@@ +=========================================================================== +libressl version 2.6.3: The Program includes libressl version 2.6.3 +software. IBM obtained the libressl version 2.6.3 software under the +terms and conditions of the following license(s): -* Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. +--------------------------------------------------------------------------- -* Neither the name of the author nor the names of its contributors may -be used to endorse or promote products derived from this software -without specific prior written permission. +LICENSE ISSUES + ============== -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS -IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED -TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A -PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED -TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +The OpenSSL toolkit stays under a dual license, i.e. both the conditions of +the OpenSSL License and the original SSLeay license apply to the toolkit. +See below for the actual license texts. In case of any license issues +related to OpenSSL please contact openssl-core@openssl.org. ---------------------------------------------------------------------------- +OpenSSL License +-------------- -Copyright (c) 2011-2012 Peter Bourgon +==================================================================== +Copyright (c) 1998-2011 The OpenSSL Project. All rights reserved. -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. ---------------------------------------------------------------------------- +3. All advertising materials mentioning features or use of this + software must display the following acknowledgment: + "This product includes software developed by the OpenSSL Project + for use in the OpenSSL Toolkit. (http://www.openssl.org/)" -Copyright (c) 2013, Patrick Mezard -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. - The names of its contributors may not be used to endorse or promote -products derived from this software without specific prior written -permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS -IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED -TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A -PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED -TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ---------------------------------------------------------------------------- - -Copyright (c) 2015 Alex Efros - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - ---------------------------------------------------------------------------- - -Copyright (c) 2012,2013 Ernest Micklei - -MIT License - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ---------------------------------------------------------------------------- - -opyright (c) 2013-2014 - Frank Schroeder - -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ---------------------------------------------------------------------------- - -Copyright (c) 2013 Mitchell Hashimoto - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - ---------------------------------------------------------------------------- - -Copyright © 2012 Greg Jones (greg.jones@gmail.com) - -Permission is hereby granted, free of charge, to any person obtaining a -copy of this software and associated documentation files (the -“Software”), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ---------------------------------------------------------------------------- - -Copyright (c) 2017 Ernest Micklei - -MIT License - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ---------------------------------------------------------------------------- - -Copyright (c) 2013 Joshua Tacoma - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ---------------------------------------------------------------------------- - -Copyright (c) Yasuhiro MATSUMOTO - -MIT License (Expat) - -Permission is hereby granted, free of charge, to any person obtaining a -copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ---------------------------------------------------------------------------- - -The MIT License (MIT) - -Copyright (c) 2016 Yasuhiro Matsumoto - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - - -======================================================================= -END OF kubernetes-incubator-external-storage version 3.0.0-beta2 -NOTICES AND INFORMATION -======================================================================= - - - -=========================================================================== -End of Notices for Apache 2.0 Licensed Codes -=========================================================================== - - -@@@@@@@@@@@@ -=========================================================================== -alpine-keys version 2.1: The Program includes alpine-keys version 2.1 -software. IBM obtained the alpine-keys version 2.1 software under the -terms and conditions of the following license(s): - ---------------------------------------------------------------------------- - -Permission is hereby granted, free of charge, to any person obtaining a -copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - -======================================================================= -END OF alpine-keys version 2.1 NOTICES AND INFORMATION -======================================================================= - - -@@@@@@@@@@@@ -=========================================================================== -CA-Certificates version 20171114: The Program includes -CA-Certificates version 20171114 software. IBM obtained the -CA-Certificates version 20171114 software under the terms and -conditions of the following license(s): - ---------------------------------------------------------------------------- - -Copyright (c) 2013-2014 Timo Teräs - -Permission is hereby granted, free of charge, to any person obtaining a -copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - - -======================================================================= -END OF CA-Certificates version 20171114 NOTICES AND INFORMATION -======================================================================= - - -@@@@@@@@@@@@ -=========================================================================== -go-flags version 1.3: The Program includes go-flags version 1.3 -software. IBM obtained the go-flags version 1.3 software under the -terms and conditions of the following license(s): - ---------------------------------------------------------------------------- - -Copyright (c) 2012 Jesse van den Kieboom. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following disclaimer - in the documentation and/or other materials provided with the - distribution. - * Neither the name of Google Inc. nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - -======================================================================= -END OF go-flags version 1.3 NOTICES AND INFORMATION -======================================================================= - - -@@@@@@@@@@@@ -=========================================================================== -go-logging version 1: The Program includes go-logging version 1 -software. IBM obtained the go-logging version 1 software under the -terms and conditions of the following license(s): - ---------------------------------------------------------------------------- - -Copyright (c) 2013 Örjan Persson. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - -======================================================================= -END OF go-logging version 1 NOTICES AND INFORMATION -======================================================================= - - -@@@@@@@@@@@@ -=========================================================================== -go-sqlite3 version 1.3.0: The Program includes go-sqlite3 version -1.3.0 software. IBM obtained the go-sqlite3 version 1.3.0 software -under the terms and conditions of the following license(s): - ---------------------------------------------------------------------------- - -The MIT License (MIT) - -Copyright (c) 2014 Yasuhiro Matsumoto - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - ---------------------------------------------------------------------------- - -Copyright 2009-2010 Cybozu Labs, Inc. -Copyright 2011 Kazuho Oku - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY CYBOZU LABS, INC. ``AS IS'' AND ANY EXPRESS OR -IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO -EVENT SHALL CYBOZU LABS, INC. OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, -INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -The views and conclusions contained in the software and documentation are -those of the authors and should not be interpreted as representing official -policies, either expressed or implied, of Cybozu Labs, Inc. - -======================================================================= -END OF go-sqlite3 version 1.3.0 NOTICES AND INFORMATION -======================================================================= - - -@@@@@@@@@@@@ -=========================================================================== -gorm version 1.0: The Program includes gorm version 1.0 software. IBM -obtained the gorm version 1.0 software under the terms and conditions -of the following license(s): - ---------------------------------------------------------------------------- - -The MIT License (MIT) - -Copyright (c) 2013-NOW Jinzhu - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - - -======================================================================= -END OF gorm version 1.0 NOTICES AND INFORMATION -======================================================================= - - -@@@@@@@@@@@@ -=========================================================================== -libressl version 2.6.3: The Program includes libressl version 2.6.3 -software. IBM obtained the libressl version 2.6.3 software under the -terms and conditions of the following license(s): - ---------------------------------------------------------------------------- - -LICENSE ISSUES - ============== - -The OpenSSL toolkit stays under a dual license, i.e. both the conditions of -the OpenSSL License and the original SSLeay license apply to the toolkit. -See below for the actual license texts. In case of any license issues -related to OpenSSL please contact openssl-core@openssl.org. - -OpenSSL License --------------- - -==================================================================== -Copyright (c) 1998-2011 The OpenSSL Project. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - -1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - -3. All advertising materials mentioning features or use of this - software must display the following acknowledgment: - "This product includes software developed by the OpenSSL Project - for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - -4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - endorse or promote products derived from this software without - prior written permission. For written permission, please contact - openssl-core@openssl.org. +4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + endorse or promote products derived from this software without + prior written permission. For written permission, please contact + openssl-core@openssl.org. 5. Products derived from this software may not be called "OpenSSL" nor may "OpenSSL" appear in their names without prior written @@ -9948,12 +9536,46 @@ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - ======================================================================= END OF libressl version 2.6.3 NOTICES AND INFORMATION ======================================================================= +@@@@@@@@@@@@ +=========================================================================== +lockfile commit level 6a197d5: The Program includes lockfile commit +level 6a197d5 software. IBM obtained the lockfile commit level +6a197d5 software under the terms and conditions of the following license(s): + +--------------------------------------------------------------------------- + +Copyright (c) 2012 Ingo Oeser + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + +======================================================================= +END OF lockfile commit level 6a197d5 NOTICES AND INFORMATION +======================================================================= + + @@@@@@@@@@@@ =========================================================================== lumberjack version 2.0: The Program includes lumberjack version 2.0 @@ -9989,6 +9611,49 @@ END OF lumberjack version 2.0 NOTICES AND INFORMATION ======================================================================= +@@@@@@@@@@@@ +=========================================================================== +mergo commit level 6633656: The Program includes mergo commit level +6633656 software. IBM obtained the mergo commit level 6633656 +software under the terms and conditions of the following license(s): + +--------------------------------------------------------------------------- + +Copyright (c) 2013 Dario Castañé. All rights reserved. +Copyright (c) 2012 The Go Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +======================================================================= +END OF mergo commit level 6633656 NOTICES AND INFORMATION +======================================================================= + + @@@@@@@@@@@@ =========================================================================== musl version 1.1.18: The Program includes musl version 1.1.18 @@ -10041,7 +9706,7 @@ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - + --------------------------------------------------------------------------- Copyright (c) 2005 Bruce D. Evans and Steven G. Kargl @@ -10058,7 +9723,7 @@ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - + --------------------------------------------------------------------------- Copyright (c) 2005 David Schultz Copyright (c) 2007 David Schultz @@ -10279,6 +9944,84 @@ END OF mux version 1.5.0 NOTICES AND INFORMATION ======================================================================= +@@@@@@@@@@@@ +=========================================================================== +net commit level 1c05540: The Program includes net commit level +1c05540 software. IBM obtained the net commit level 1c05540 software +under the terms and conditions of the following license(s): + +--------------------------------------------------------------------------- + +Copyright (c) 2009 The Go Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +======================================================================= +END OF net commit level 1c05540 NOTICES AND INFORMATION +======================================================================= + + +@@@@@@@@@@@@ +=========================================================================== +nightlyone-lockfile commit level 6a197d5: The Program includes +nightlyone-lockfile commit level 6a197d5 software. IBM obtained the +nightlyone-lockfile commit level 6a197d5 software under the terms and +conditions of the following license(s): + +--------------------------------------------------------------------------- + +Copyright (c) 2012 Ingo Oeser + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + +======================================================================= +END OF nightlyone-lockfile commit level 6a197d5 NOTICES AND +INFORMATION +======================================================================= + + @@@@@@@@@@@@ =========================================================================== OpenSSL version 1.0.2o: The Program includes OpenSSL version 1.0.2o @@ -10360,21 +10103,21 @@ Original SSLeay License This package is an SSL implementation written by Eric Young (eay@cryptsoft.com). The implementation was written so as to conform with Netscapes SSL. - + This library is free for commercial and non-commercial use as long as the following conditions are aheared to. The following conditions apply to all code found in this distribution, be it the RC4, RSA, lhash, DES, etc., code; not just the SSL code. The SSL documentation included with this distribution is covered by the same copyright terms except that the holder is Tim Hudson (tjh@cryptsoft.com). - + Copyright remains Eric Young's, and as such any Copyright notices in the code are not to be removed. If this package is used in a product, Eric Young should be given attribution as the author of the parts of the library used. This can be in the form of a textual message at program startup or in documentation (online or textual) provided with the package. - + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -10392,7 +10135,7 @@ Original SSLeay License 4. If you include any Windows specific code (or a derivative thereof) from the apps directory (application code) you must include an acknowledgement: "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - + THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE @@ -10404,16 +10147,16 @@ Original SSLeay License LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - + The licence and distribution terms for any publically available version or derivative of this code cannot be changed. i.e. this code cannot simply be copied and put under another distribution licence [including the GNU Public Licence.] - + =========================================================================== - + Copyright Notices: - + --------------------------------------------------------------------------- Copyright (c) 1998-1999 The OpenSSL Project. All rights reserved. @@ -10540,7 +10283,7 @@ Copyright (c) 2004, Richard Levitte THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - + --------------------------------------------------------------------------- Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) @@ -10602,26 +10345,26 @@ Copyright (c) 2004, Richard Levitte --------------------------------------------------------------------------- Copyright (c) 2012, Intel Corporation - + All rights reserved. - + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - + * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - + * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - + * Neither the name of the Intel Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. - - + + THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION ""AS IS"" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR @@ -10659,187 +10402,453 @@ Copyright (c) 2004, Richard Levitte LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - + +--------------------------------------------------------------------------- + + Copyright (c) 2005 Hewlett-Packard Development Company, L.P. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +--------------------------------------------------------------------------- + +Copyright (c) 2004 Kungliga Tekniska Högskolan + (Royal Institute of Technology, Stockholm, Sweden). + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of the Institute nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + +--------------------------------------------------------------------------- + + Copyright (c) 2002 Bob Beck + Copyright (c) 2002 Theo de Raadt + Copyright (c) 2002 Markus Friedl + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +--------------------------------------------------------------------------- + + Copyright 1998-2000 nCipher Corporation Limited. + + Redistribution and use in source and binary forms, with opr without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above + copyright notice, this list of conditions, and the following + disclaimer, in the documentation and/or other materials provided + with the distribution + + IN NO EVENT SHALL NCIPHER CORPORATION LIMITED (`NCIPHER') AND/OR + ANY OTHER AUTHORS OR DISTRIBUTORS OF THIS FILE BE LIABLE for any + damages arising directly or indirectly from this file, its use or + this licence. Without prejudice to the generality of the + foregoing: all liability shall be excluded for direct, indirect, + special, incidental, consequential or other damages or any loss of + profits, business, revenue goodwill or anticipated savings; + liability shall be excluded even if nCipher or anyone else has been + advised of the possibility of damage. In any event, if the + exclusion of liability is not effective, the liability of nCipher + or any author or distributor shall be limited to the lesser of the + price paid and 1,000 pounds sterling. This licence only fails to + exclude or limit liability for death or personal injury arising out + of negligence, and only to the extent that such an exclusion or + limitation is not effective. + + NCIPHER AND THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ALL + AND ANY WARRANTIES (WHETHER EXPRESS OR IMPLIED), including, but not + limited to, any implied warranties of merchantability, fitness for + a particular purpose, satisfactory quality, and/or non-infringement + of any third party rights. + + US Government use: This software and documentation is Commercial + Computer Software and Computer Software Documentation, as defined in + sub-paragraphs (a)(1) and (a)(5) of DFAR 252.227-7014, "Rights in + Noncommercial Computer Software and Noncommercial Computer Software + Documentation." Use, duplication or disclosure by the Government is + subject to the terms and conditions specified here. + + By using or distributing this file you will be accepting these + terms and conditions, including the limitation of liability and + lack of warranty. If you do not wish to accept these terms and + conditions, DO NOT USE THE FILE. + + + The actual dynamically loadable plugin, and the library files for + static linking, which are also provided in some distributions, are + not covered by the licence described above. You should have + received a separate licence with terms and conditions for these + library files; if you received the library files without a licence, + please contact nCipher. + + +======================================================================= +END OF OpenSSL version 1.0.2o NOTICES AND INFORMATION +======================================================================= + + +@@@@@@@@@@@@ +=========================================================================== +pflag commit level 5ccb023: The Program includes pflag commit level +5ccb023 software. IBM obtained the pflag commit level 5ccb023 +software under the terms and conditions of the following license(s): + +--------------------------------------------------------------------------- + +Copyright (c) 2012 Alex Ogier. All rights reserved. +Copyright (c) 2012 The Go Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +======================================================================= +END OF pflag commit level 5ccb023 NOTICES AND INFORMATION +======================================================================= + + +@@@@@@@@@@@@ +=========================================================================== +pq commit level 90697d6: The Program includes pq commit level 90697d6 +software. IBM obtained the pq commit level 90697d6 software under the +terms and conditions of the following license(s): + +--------------------------------------------------------------------------- + +Copyright (c) 2011-2013, 'pq' Contributors +Portions Copyright (C) 2011 Blake Mizerany + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + +======================================================================= +END OF pq commit level 90697d6 NOTICES AND INFORMATION +======================================================================= + + +@@@@@@@@@@@@ +=========================================================================== +protobuf commit level 1643683: The Program includes protobuf commit +level 1643683 software. IBM obtained the protobuf commit level +1643683 software under the terms and conditions of the following license(s): + --------------------------------------------------------------------------- - Copyright (c) 2005 Hewlett-Packard Development Company, L.P. +Go support for Protocol Buffers - Google's data interchange format + +Copyright 2010 The Go Authors. All rights reserved. +https://github.com/golang/protobuf + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - "Software"), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: +======================================================================= +END OF protobuf commit level 1643683 NOTICES AND INFORMATION +======================================================================= - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - +@@@@@@@@@@@@ +=========================================================================== +protobuf commit level c0656ed: The Program includes protobuf commit +level c0656ed software. IBM obtained the protobuf commit level +c0656ed software under the terms and conditions of the following license(s): + --------------------------------------------------------------------------- -Copyright (c) 2004 Kungliga Tekniska Högskolan - (Royal Institute of Technology, Stockholm, Sweden). - All rights reserved. +Protocol Buffers for Go with Gadgets - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: +Copyright (c) 2013, The GoGo Authors. All rights reserved. +http://github.com/gogo/protobuf - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. +Go support for Protocol Buffers - Google's data interchange format - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. +Copyright 2010 The Go Authors. All rights reserved. +https://github.com/golang/protobuf - 3. Neither the name of the Institute nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: - THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - SUCH DAMAGE. + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. ---------------------------------------------------------------------------- +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - Copyright (c) 2002 Bob Beck - Copyright (c) 2002 Theo de Raadt - Copyright (c) 2002 Markus Friedl - All rights reserved. - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. +======================================================================= +END OF protobuf commit level c0656ed NOTICES AND INFORMATION +======================================================================= - THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY - EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +@@@@@@@@@@@@ +=========================================================================== +purell commit level 8a29053: The Program includes purell commit level +8a29053 software. IBM obtained the purell commit level 8a29053 +software under the terms and conditions of the following license(s): --------------------------------------------------------------------------- - Copyright 1998-2000 nCipher Corporation Limited. +Copyright (c) 2012, Martin Angers +All rights reserved. - Redistribution and use in source and binary forms, with opr without - modification, are permitted provided that the following conditions - are met: +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: - 1. Redistributions of source code must retain the copyright notice, - this list of conditions, and the following disclaimer. +* Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above - copyright notice, this list of conditions, and the following - disclaimer, in the documentation and/or other materials provided - with the distribution +* Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. - IN NO EVENT SHALL NCIPHER CORPORATION LIMITED (`NCIPHER') AND/OR - ANY OTHER AUTHORS OR DISTRIBUTORS OF THIS FILE BE LIABLE for any - damages arising directly or indirectly from this file, its use or - this licence. Without prejudice to the generality of the - foregoing: all liability shall be excluded for direct, indirect, - special, incidental, consequential or other damages or any loss of - profits, business, revenue goodwill or anticipated savings; - liability shall be excluded even if nCipher or anyone else has been - advised of the possibility of damage. In any event, if the - exclusion of liability is not effective, the liability of nCipher - or any author or distributor shall be limited to the lesser of the - price paid and 1,000 pounds sterling. This licence only fails to - exclude or limit liability for death or personal injury arising out - of negligence, and only to the extent that such an exclusion or - limitation is not effective. +* Neither the name of the author nor the names of its contributors may +be used to endorse or promote products derived from this software +without specific prior written permission. - NCIPHER AND THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ALL - AND ANY WARRANTIES (WHETHER EXPRESS OR IMPLIED), including, but not - limited to, any implied warranties of merchantability, fitness for - a particular purpose, satisfactory quality, and/or non-infringement - of any third party rights. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED +TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - US Government use: This software and documentation is Commercial - Computer Software and Computer Software Documentation, as defined in - sub-paragraphs (a)(1) and (a)(5) of DFAR 252.227-7014, "Rights in - Noncommercial Computer Software and Noncommercial Computer Software - Documentation." Use, duplication or disclosure by the Government is - subject to the terms and conditions specified here. - By using or distributing this file you will be accepting these - terms and conditions, including the limitation of liability and - lack of warranty. If you do not wish to accept these terms and - conditions, DO NOT USE THE FILE. +======================================================================= +END OF purell commit level 8a29053 NOTICES AND INFORMATION +======================================================================= - The actual dynamically loadable plugin, and the library files for - static linking, which are also provided in some distributions, are - not covered by the licence described above. You should have - received a separate licence with terms and conditions for these - library files; if you received the library files without a licence, - please contact nCipher. - +@@@@@@@@@@@@ +=========================================================================== +sys commit level a2e06a1: The Program includes sys commit level +a2e06a1 software. IBM obtained the sys commit level a2e06a1 software +under the terms and conditions of the following license(s): + +--------------------------------------------------------------------------- + +Copyright (c) 2009 The Go Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ======================================================================= -END OF OpenSSL version 1.0.2o NOTICES AND INFORMATION +END OF sys commit level a2e06a1 NOTICES AND INFORMATION ======================================================================= @@@@@@@@@@@@ =========================================================================== -nightlyone-lockfile version 6a197d5: The Program includes -nightlyone-lockfile version 6a197d5 software. IBM obtained the -nightlyone-lockfile version 6a197d5 software under the terms and -conditions of the following license(s): +text commit level b19bf47: The Program includes text commit level +b19bf47 software. IBM obtained the text commit level b19bf47 software +under the terms and conditions of the following license(s): --------------------------------------------------------------------------- -Copyright (c) 2012 Ingo Oeser +Copyright (c) 2009 The Go Authors. All rights reserved. -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ======================================================================= -END OF nightlyone-lockfile version 6a197d5 NOTICES AND -INFORMATION +END OF text commit level b19bf47 NOTICES AND INFORMATION ======================================================================= @@ -10879,6 +10888,158 @@ END OF times version 1.0.1 NOTICES AND INFORMATION ======================================================================= +@@@@@@@@@@@@ +=========================================================================== +urlesc commit level 5bd2802: The Program includes urlesc commit level +5bd2802 software. IBM obtained the urlesc commit level 5bd2802 +software under the terms and conditions of the following license(s): + +--------------------------------------------------------------------------- + +Copyright (c) 2012 The Go Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +======================================================================= +END OF urlesc commit level 5bd2802 NOTICES AND INFORMATION +======================================================================= + + +@@@@@@@@@@@@ +=========================================================================== +uuid commit level ca53cad: The Program includes uuid commit level +ca53cad software. IBM obtained the uuid commit level ca53cad software +under the terms and conditions of the following license(s): + +--------------------------------------------------------------------------- + +Copyright (c) 2009,2014 Google Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +======================================================================= +END OF uuid commit level ca53cad NOTICES AND INFORMATION +======================================================================= + + +@@@@@@@@@@@@ +=========================================================================== +yaml commit level 73d445a: The Program includes yaml commit level +73d445a software. IBM obtained the yaml commit level 73d445a software +under the terms and conditions of the following license(s): + +--------------------------------------------------------------------------- + +The MIT License (MIT) + +Copyright (c) 2014 Sam Ghods + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + +--------------------------------------------------------------------------- + +Copyright (c) 2012 The Go Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +======================================================================= +END OF yaml commit level 73d445a NOTICES AND INFORMATION +======================================================================= + + @@@@@@@@@@@@ =========================================================================== zlib version 1.2.11: The Program includes zlib version 1.2.11 @@ -10888,21 +11049,21 @@ terms and conditions of the following license(s): --------------------------------------------------------------------------- Boost Software License - Version 1.0 - August 17th, 2003 - + Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and accompanying documentation covered by this license (the "Software") to use, reproduce, display, distribute, execute, and transmit the Software, and to prepare derivative works of the Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the following: - + The copyright notices in the Software and this entire statement, including the above license grant, this restriction and the following disclaimer, must be included in all copies of the Software, in whole or in part, and all derivative works of the Software, unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. - + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT @@ -10910,7 +11071,7 @@ terms and conditions of the following license(s): FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - + =========================================================================== Copyright Notices: ---------------------------------------------------------------------------_ @@ -10920,7 +11081,7 @@ Copyright Notices: Advanced Computing Fantoftvegen 38, 5036 BERGEN, Norway http://www.cmr.no - + Permission to use, copy, modify, distribute and sell this software and its documentation for any purpose is hereby granted without fee, provided that the above copyright notice appear in all copies and @@ -10928,25 +11089,25 @@ Copyright Notices: in supporting documentation. Christian Michelsen Research AS makes no representations about the suitability of this software for any purpose. It is provided "as is" without express or implied warranty - + --------------------------------------------------------------------------- - + Copyright (C) 1995-2010 Jean-loup Gailly, Brian Raiter and Gilles Vollant. - + File written by Gilles Vollant, by converting to assembly the longest_match from Jean-loup Gailly in deflate.c of zLib and infoZip zip. - + and by taking inspiration on asm686 with masm, optimised assembly code from Brian Raiter, written 1998 - + This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. - + Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: - + 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be @@ -10959,16 +11120,16 @@ Copyright Notices: Copyright (C) 1998 Brian Raiter You can look at http://www.muppetlabs.com/~breadbox/software/assembly.html - - + + This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. - + Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: - + 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be @@ -10976,27 +11137,27 @@ Copyright Notices: 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software 3. This notice may not be removed or altered from any source distribution. - + _--------------------------------------------------------------------------- The zlibpas interface is: Copyright (C) 1995-2003 Jean-loup Gailly and Mark Adler. Copyright (C) 1998 by Bob Dellaca. Copyright (C) 2003 by Cosmin Truta. - + The example program is: Copyright (C) 1995-2003 by Jean-loup Gailly. Copyright (C) 1998,1999,2000 by Jacques Nomssi Nzali. Copyright (C) 2003 by Cosmin Truta. - + This software is provided 'as-is', without any express or implied warranty. In no event will the author be held liable for any damages arising from the use of this software. - + Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: - + 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be @@ -11004,7 +11165,7 @@ _--------------------------------------------------------------------------- 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. - + --------------------------------------------------------------------------- Copyright (C) 2002-2013 Mark Adler, all rights reserved @@ -11101,7 +11262,7 @@ _--------------------------------------------------------------------------- 3. This notice may not be removed or altered from any source distribution. --------------------------------------------------------------------------- - + Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler Copyright (C) 1995-2016 Jean-loup Gailly and Mark Adler Copyright (C) 1995-2017 Jean-loup Gailly and Mark Adler @@ -11136,12 +11297,349 @@ The Program includes some or all of the following that IBM obtained under the Common Development and Distribution License (source code available via the indicated URL): -kubernetes-incubator-external -storage +kubernetes-incubator-external-storage commit level 92295a3 (http://github.com/kubernetes-incubator/external-storage) - -kubernetes version 1.8 + +Portions of kubernetes version 1.9.2 (https://github.com/kubernetes/kubernetes) +--------------------------------------------------------------------------- + +COMMON DEVELOPMENT AND DISTRIBUTION LICENSE Version 1.0 (CDDL-1.0) + +1. Definitions. + +1.1. Contributor means each individual or entity that creates or +contributes to the creation of Modifications. + +1.2. Contributor Version means the combination of the Original Software, +prior Modifications used by a Contributor (if any), and the +Modifications made by that particular Contributor. + +1.3. Covered Software means (a) the Original Software, or (b) +Modifications, or (c) the combination of files containing Original +Software with files containing Modifications, in each case including +portions thereof. + +1.4. Executable means the Covered Software in any form other than Source +Code. + +1.5. Initial Developer means the individual or entity that first makes +Original Software available under this License. + +1.6. Larger Work means a work which combines Covered Software or +portions thereof with code not governed by the terms of this License. + +1.7. License means this document. + +1.8. Licensable means having the right to grant, to the maximum extent +possible, whether at the time of the initial grant or subsequently +acquired, any and all of the rights conveyed herein. + +1.9. Modifications means the Source Code and Executable form of any of +the following: + +A. Any file that results from an addition to, deletion from or +modification of the contents of a file containing Original Software or +previous Modifications; + +B. Any new file that contains any part of the Original Software or +previous Modification; or + +C. Any new file that is contributed or otherwise made available under +the terms of this License. + +1.10. Original Software means the Source Code and Executable form of +computer software code that is originally released under this License. + +1.11. Patent Claims means any patent claim(s), now owned or hereafter +acquired, including without limitation, method, process, and apparatus +claims, in any patent Licensable by grantor. + +1.12. Source Code means (a) the common form of computer software code in +which modifications are made and (b) associated documentation included +in or with such code. + +1.13. You (or Your) means an individual or a legal entity exercising +rights under, and complying with all of the terms of, this License. For +legal entities, You includes any entity which controls, is controlled +by, or is under common control with You. For purposes of this +definition, control means (a) the power, direct or indirect, to cause +the direction or management of such entity, whether by contract or +otherwise, or (b) ownership of more than fifty percent (50%) of the +outstanding shares or beneficial ownership of such entity. + +2. License Grants. + +2.1. The Initial Developer Grant. + +Conditioned upon Your compliance with Section 3.1 below and subject to +third party intellectual property claims, the Initial Developer hereby +grants You a world-wide, royalty-free, non-exclusive license: + +(a) under intellectual property rights (other than patent or trademark) +Licensable by Initial Developer, to use, reproduce, modify, display, +perform, sublicense and distribute the Original Software (or portions +thereof), with or without Modifications, and/or as part of a Larger +Work; and + +(b) under Patent Claims infringed by the making, using or selling of +Original Software, to make, have made, use, practice, sell, and offer +for sale, and/or otherwise dispose of the Original Software (or portions +thereof). + +(c) The licenses granted in Sections 2.1(a) and (b) are effective on the +date Initial Developer first distributes or otherwise makes the Original +Software available to a third party under the terms of this License. + +(d) Notwithstanding Section 2.1(b) above, no patent license is granted: +(1) for code that You delete from the Original Software, or (2) for +infringements caused by: (i) the modification of the Original Software, +or (ii) the combination of the Original Software with other software or +devices. + +2.2. Contributor Grant. + +Conditioned upon Your compliance with Section 3.1 below and subject to +third party intellectual property claims, each Contributor hereby grants +You a world-wide, royalty-free, non-exclusive license: + +(a) under intellectual property rights (other than patent or trademark) +Licensable by Contributor to use, reproduce, modify, display, perform, +sublicense and distribute the Modifications created by such Contributor +(or portions thereof), either on an unmodified basis, with other +Modifications, as Covered Software and/or as part of a Larger Work; and + +(b) under Patent Claims infringed by the making, using, or selling of +Modifications made by that Contributor either alone and/or in +combination with its Contributor Version (or portions of such +combination), to make, use, sell, offer for sale, have made, and/or +otherwise dispose of: (1) Modifications made by that Contributor (or +portions thereof); and (2) the combination of Modifications made by that +Contributor with its Contributor Version (or portions of such +combination). + +(c) The licenses granted in Sections 2.2(a) and 2.2(b) are effective on +the date Contributor first distributes or otherwise makes the +Modifications available to a third party. + +(d) Notwithstanding Section 2.2(b) above, no patent license is granted: +(1) for any code that Contributor has deleted from the Contributor +Version; (2) for infringements caused by: (i) third party modifications +of Contributor Version, or (ii) the combination of Modifications made by +that Contributor with other software (except as part of the Contributor +Version) or other devices; or (3) under Patent Claims infringed by +Covered Software in the absence of Modifications made by that +Contributor. + +3. Distribution Obligations. + +3.1. Availability of Source Code. + +Any Covered Software that You distribute or otherwise make available in +Executable form must also be made available in Source Code form and that +Source Code form must be distributed only under the terms of this +License. You must include a copy of this License with every copy of the +Source Code form of the Covered Software You distribute or otherwise +make available. You must inform recipients of any such Covered Software +in Executable form as to how they can obtain such Covered Software in +Source Code form in a reasonable manner on or through a medium +customarily used for software exchange. + +3.2. Modifications. + +The Modifications that You create or to which You contribute are +governed by the terms of this License. You represent that You believe +Your Modifications are Your original creation(s) and/or You have +sufficient rights to grant the rights conveyed by this License. + +3.3. Required Notices. + +You must include a notice in each of Your Modifications that identifies +You as the Contributor of the Modification. You may not remove or alter +any copyright, patent or trademark notices contained within the Covered +Software, or any notices of licensing or any descriptive text giving +attribution to any Contributor or the Initial Developer. + +3.4. Application of Additional Terms. + +You may not offer or impose any terms on any Covered Software in Source +Code form that alters or restricts the applicable version of this +License or the recipients rights hereunder. You may choose to offer, and +to charge a fee for, warranty, support, indemnity or liability +obligations to one or more recipients of Covered Software. However, you +may do so only on Your own behalf, and not on behalf of the Initial +Developer or any Contributor. You must make it absolutely clear that any +such warranty, support, indemnity or liability obligation is offered by +You alone, and You hereby agree to indemnify the Initial Developer and +every Contributor for any liability incurred by the Initial Developer or +such Contributor as a result of warranty, support, indemnity or +liability terms You offer. + +3.5. Distribution of Executable Versions. + +You may distribute the Executable form of the Covered Software under the +terms of this License or under the terms of a license of Your choice, +which may contain terms different from this License, provided that You +are in compliance with the terms of this License and that the license +for the Executable form does not attempt to limit or alter the +recipients rights in the Source Code form from the rights set forth in +this License. If You distribute the Covered Software in Executable form +under a different license, You must make it absolutely clear that any +terms which differ from this License are offered by You alone, not by +the Initial Developer or Contributor. You hereby agree to indemnify the +Initial Developer and every Contributor for any liability incurred by +the Initial Developer or such Contributor as a result of any such terms +You offer. + +3.6. Larger Works. + +You may create a Larger Work by combining Covered Software with other +code not governed by the terms of this License and distribute the Larger +Work as a single product. In such a case, You must make sure the +requirements of this License are fulfilled for the Covered Software. + +4. Versions of the License. + +4.1. New Versions. + +Sun Microsystems, Inc. is the initial license steward and may publish +revised and/or new versions of this License from time to time. Each +version will be given a distinguishing version number. Except as +provided in Section 4.3, no one other than the license steward has the +right to modify this License. + +4.2. Effect of New Versions. + +You may always continue to use, distribute or otherwise make the Covered +Software available under the terms of the version of the License under +which You originally received the Covered Software. If the Initial +Developer includes a notice in the Original Software prohibiting it from +being distributed or otherwise made available under any subsequent +version of the License, You must distribute and make the Covered +Software available under the terms of the version of the License under +which You originally received the Covered Software. Otherwise, You may +also choose to use, distribute or otherwise make the Covered Software +available under the terms of any subsequent version of the License +published by the license steward. + +4.3. Modified Versions. + +When You are an Initial Developer and You want to create a new license +for Your Original Software, You may create and use a modified version of +this License if You: (a) rename the license and remove any references to +the name of the license steward (except to note that the license differs +from this License); and (b) otherwise make it clear that the license +contains terms which differ from this License. + +5. DISCLAIMER OF WARRANTY. + +COVERED SOFTWARE IS PROVIDED UNDER THIS LICENSE ON AN AS IS BASIS, +WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, +WITHOUT LIMITATION, WARRANTIES THAT THE COVERED SOFTWARE IS FREE OF +DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING. +THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED +SOFTWARE IS WITH YOU. SHOULD ANY COVERED SOFTWARE PROVE DEFECTIVE IN ANY +RESPECT, YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME +THE COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS +DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO +USE OF ANY COVERED SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS +DISCLAIMER. + +6. TERMINATION. + +6.1. This License and the rights granted hereunder will terminate +automatically if You fail to comply with terms herein and fail to cure +such breach within 30 days of becoming aware of the breach. Provisions +which, by their nature, must remain in effect beyond the termination of +this License shall survive. + +6.2. If You assert a patent infringement claim (excluding declaratory +judgment actions) against Initial Developer or a Contributor (the +Initial Developer or Contributor against whom You assert such claim is +referred to as Participant) alleging that the Participant Software +(meaning the Contributor Version where the Participant is a Contributor +or the Original Software where the Participant is the Initial Developer) +directly or indirectly infringes any patent, then any and all rights +granted directly or indirectly to You by such Participant, the Initial +Developer (if the Initial Developer is not the Participant) and all +Contributors under Sections 2.1 and/or 2.2 of this License shall, upon +60 days notice from Participant terminate prospectively and +automatically at the expiration of such 60 day notice period, unless if +within such 60 day period You withdraw Your claim with respect to the +Participant Software against such Participant either unilaterally or +pursuant to a written agreement with Participant. + +6.3. In the event of termination under Sections 6.1 or 6.2 above, all +end user licenses that have been validly granted by You or any +distributor hereunder prior to termination (excluding licenses granted +to You by any distributor) shall survive termination. + +7. LIMITATION OF LIABILITY. + +UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT +(INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL +DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED +SOFTWARE, OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY +PERSON FOR ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES +OF ANY CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOST +PROFITS, LOSS OF GOODWILL, WORK STOPPAGE, COMPUTER FAILURE OR +MALFUNCTION, OR ANY AND ALL OTHER COMMERCIAL DAMAGES OR LOSSES, EVEN IF +SUCH PARTY SHALL HAVE BEEN INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. +THIS LIMITATION OF LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR +PERSONAL INJURY RESULTING FROM SUCH PARTYS NEGLIGENCE TO THE EXTENT +APPLICABLE LAW PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT +ALLOW THE EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL +DAMAGES, SO THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU. + +8. U.S. GOVERNMENT END USERS. + +The Covered Software is a commercial item, as that term is defined in 48 +C.F.R. 2.101 (Oct. 1995), consisting of commercial computer software (as +that term is defined at 48 C.F.R. 252.227-7014(a)(1)) and commercial +computer software documentation as such terms are used in 48 C.F.R. +12.212 (Sept. 1995). Consistent with 48 C.F.R. 12.212 and 48 C.F.R. +227.7202-1 through 227.7202-4 (June 1995), all U.S. Government End Users +acquire Covered Software with only those rights set forth herein. This +U.S. Government Rights clause is in lieu of, and supersedes, any other +FAR, DFAR, or other clause or provision that addresses Government rights +in computer software under this License. + +9. MISCELLANEOUS. + +This License represents the complete agreement concerning subject matter +hereof. If any provision of this License is held to be unenforceable, +such provision shall be reformed only to the extent necessary to make it +enforceable. This License shall be governed by the law of the +jurisdiction specified in a notice contained within the Original +Software (except to the extent applicable law, if any, provides +otherwise), excluding such jurisdictions conflict-of-law provisions. Any +litigation relating to this License shall be subject to the jurisdiction +of the courts located in the jurisdiction and venue specified in a +notice contained within the Original Software, with the losing party +responsible for costs, including, without limitation, court costs and +reasonable attorneys fees and expenses. The application of the United +Nations Convention on Contracts for the International Sale of Goods is +expressly excluded. Any law or regulation which provides that the +language of a contract shall be construed against the drafter shall not +apply to this License. You agree that You alone are responsible for +compliance with the United States export administration regulations (and +the export control laws and regulation of any other countries) when You +use, distribute or otherwise make available any Covered Software. + +10. RESPONSIBILITY FOR CLAIMS. + +As between Initial Developer and the Contributors, each party is +responsible for claims and damages arising, directly or indirectly, out +of its utilization of rights under this License and You agree to work +with Initial Developer and Contributors to distribute such +responsibility on an equitable basis. Nothing herein is intended or +shall be deemed to constitute any admission of liability. + +Opensource.org site content is licensed under a Creative Commons +Attribution 4.0 International License. Hosting for Opensource.org is +generously provided by DigitalOcean. Please see Terms of Service. + ======================================================================= END Common Development and Distribution License @@ -11156,15 +11654,384 @@ The Program includes some or all of the following that IBM obtained under the Mozilla PuIblic License, Version 2.0 (source code available via the indicated URL): -kubernetes-incubator-external-storage version 3.0.0-beta.2 +kubernetes-incubator-external-storage commit level 92295a3 (http://github.com/kubernetes-incubator/external-storage) - -kubernetes version 1.8 + +Portions of kubernetes version 1.9.2 (https://github.com/kubernetes/kubernetes) - + CA-Certificates version 20171114 (https://github.com/alpinelinux/ca-certificates) - + +golang-lru commit level a0d98a5 + (https://github.com/hashicorp/golang-lru) + +--------------------------------------------------------------------------- + +Mozilla Public License, version 2.0 + +1. Definitions + +1.1. "Contributor" + + means each individual or legal entity that creates, contributes to the + creation of, or owns Covered Software. + +1.2. "Contributor Version" + + means the combination of the Contributions of others (if any) used by a + Contributor and that particular Contributor's Contribution. + +1.3. "Contribution" + + means Covered Software of a particular Contributor. + +1.4. "Covered Software" + + means Source Code Form to which the initial Contributor has attached the + notice in Exhibit A, the Executable Form of such Source Code Form, and + Modifications of such Source Code Form, in each case including portions + thereof. + +1.5. "Incompatible With Secondary Licenses" + means + + a. that the initial Contributor has attached the notice described in + Exhibit B to the Covered Software; or + + b. that the Covered Software was made available under the terms of + version 1.1 or earlier of the License, but not also under the terms of + a Secondary License. + +1.6. "Executable Form" + + means any form of the work other than Source Code Form. + +1.7. "Larger Work" + + means a work that combines Covered Software with other material, in a + separate file or files, that is not Covered Software. + +1.8. "License" + + means this document. + +1.9. "Licensable" + + means having the right to grant, to the maximum extent possible, whether + at the time of the initial grant or subsequently, any and all of the + rights conveyed by this License. + +1.10. "Modifications" + + means any of the following: + + a. any file in Source Code Form that results from an addition to, + deletion from, or modification of the contents of Covered Software; or + + b. any new file in Source Code Form that contains any Covered Software. + +1.11. "Patent Claims" of a Contributor + + means any patent claim(s), including without limitation, method, + process, and apparatus claims, in any patent Licensable by such + Contributor that would be infringed, but for the grant of the License, + by the making, using, selling, offering for sale, having made, import, + or transfer of either its Contributions or its Contributor Version. + +1.12. "Secondary License" + + means either the GNU General Public License, Version 2.0, the GNU Lesser + General Public License, Version 2.1, the GNU Affero General Public + License, Version 3.0, or any later versions of those licenses. + +1.13. "Source Code Form" + + means the form of the work preferred for making modifications. + +1.14. "You" (or "Your") + + means an individual or a legal entity exercising rights under this + License. For legal entities, "You" includes any entity that controls, is + controlled by, or is under common control with You. For purposes of this + definition, "control" means (a) the power, direct or indirect, to cause + the direction or management of such entity, whether by contract or + otherwise, or (b) ownership of more than fifty percent (50%) of the + outstanding shares or beneficial ownership of such entity. + + +2. License Grants and Conditions + +2.1. Grants + + Each Contributor hereby grants You a world-wide, royalty-free, + non-exclusive license: + + a. under intellectual property rights (other than patent or trademark) + Licensable by such Contributor to use, reproduce, make available, + modify, display, perform, distribute, and otherwise exploit its + Contributions, either on an unmodified basis, with Modifications, or + as part of a Larger Work; and + + b. under Patent Claims of such Contributor to make, use, sell, offer for + sale, have made, import, and otherwise transfer either its + Contributions or its Contributor Version. + +2.2. Effective Date + + The licenses granted in Section 2.1 with respect to any Contribution + become effective for each Contribution on the date the Contributor first + distributes such Contribution. + +2.3. Limitations on Grant Scope + + The licenses granted in this Section 2 are the only rights granted under + this License. No additional rights or licenses will be implied from the + distribution or licensing of Covered Software under this License. + Notwithstanding Section 2.1(b) above, no patent license is granted by a + Contributor: + + a. for any code that a Contributor has removed from Covered Software; or + + b. for infringements caused by: (i) Your and any other third party's + modifications of Covered Software, or (ii) the combination of its + Contributions with other software (except as part of its Contributor + Version); or + + c. under Patent Claims infringed by Covered Software in the absence of + its Contributions. + + This License does not grant any rights in the trademarks, service marks, + or logos of any Contributor (except as may be necessary to comply with + the notice requirements in Section 3.4). + +2.4. Subsequent Licenses + + No Contributor makes additional grants as a result of Your choice to + distribute the Covered Software under a subsequent version of this + License (see Section 10.2) or under the terms of a Secondary License (if + permitted under the terms of Section 3.3). + +2.5. Representation + + Each Contributor represents that the Contributor believes its + Contributions are its original creation(s) or it has sufficient rights to + grant the rights to its Contributions conveyed by this License. + +2.6. Fair Use + + This License is not intended to limit any rights You have under + applicable copyright doctrines of fair use, fair dealing, or other + equivalents. + +2.7. Conditions + + Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in + Section 2.1. + + +3. Responsibilities + +3.1. Distribution of Source Form + + All distribution of Covered Software in Source Code Form, including any + Modifications that You create or to which You contribute, must be under + the terms of this License. You must inform recipients that the Source + Code Form of the Covered Software is governed by the terms of this + License, and how they can obtain a copy of this License. You may not + attempt to alter or restrict the recipients' rights in the Source Code + Form. + +3.2. Distribution of Executable Form + + If You distribute Covered Software in Executable Form then: + + a. such Covered Software must also be made available in Source Code Form, + as described in Section 3.1, and You must inform recipients of the + Executable Form how they can obtain a copy of such Source Code Form by + reasonable means in a timely manner, at a charge no more than the cost + of distribution to the recipient; and + + b. You may distribute such Executable Form under the terms of this + License, or sublicense it under different terms, provided that the + license for the Executable Form does not attempt to limit or alter the + recipients' rights in the Source Code Form under this License. + +3.3. Distribution of a Larger Work + + You may create and distribute a Larger Work under terms of Your choice, + provided that You also comply with the requirements of this License for + the Covered Software. If the Larger Work is a combination of Covered + Software with a work governed by one or more Secondary Licenses, and the + Covered Software is not Incompatible With Secondary Licenses, this + License permits You to additionally distribute such Covered Software + under the terms of such Secondary License(s), so that the recipient of + the Larger Work may, at their option, further distribute the Covered + Software under the terms of either this License or such Secondary + License(s). + +3.4. Notices + + You may not remove or alter the substance of any license notices + (including copyright notices, patent notices, disclaimers of warranty, or + limitations of liability) contained within the Source Code Form of the + Covered Software, except that You may alter any license notices to the + extent required to remedy known factual inaccuracies. + +3.5. Application of Additional Terms + + You may choose to offer, and to charge a fee for, warranty, support, + indemnity or liability obligations to one or more recipients of Covered + Software. However, You may do so only on Your own behalf, and not on + behalf of any Contributor. You must make it absolutely clear that any + such warranty, support, indemnity, or liability obligation is offered by + You alone, and You hereby agree to indemnify every Contributor for any + liability incurred by such Contributor as a result of warranty, support, + indemnity or liability terms You offer. You may include additional + disclaimers of warranty and limitations of liability specific to any + jurisdiction. + +4. Inability to Comply Due to Statute or Regulation + + If it is impossible for You to comply with any of the terms of this License + with respect to some or all of the Covered Software due to statute, + judicial order, or regulation then You must: (a) comply with the terms of + this License to the maximum extent possible; and (b) describe the + limitations and the code they affect. Such description must be placed in a + text file included with all distributions of the Covered Software under + this License. Except to the extent prohibited by statute or regulation, + such description must be sufficiently detailed for a recipient of ordinary + skill to be able to understand it. + +5. Termination + +5.1. The rights granted under this License will terminate automatically if You + fail to comply with any of its terms. However, if You become compliant, + then the rights granted under this License from a particular Contributor + are reinstated (a) provisionally, unless and until such Contributor + explicitly and finally terminates Your grants, and (b) on an ongoing + basis, if such Contributor fails to notify You of the non-compliance by + some reasonable means prior to 60 days after You have come back into + compliance. Moreover, Your grants from a particular Contributor are + reinstated on an ongoing basis if such Contributor notifies You of the + non-compliance by some reasonable means, this is the first time You have + received notice of non-compliance with this License from such + Contributor, and You become compliant prior to 30 days after Your receipt + of the notice. + +5.2. If You initiate litigation against any entity by asserting a patent + infringement claim (excluding declaratory judgment actions, + counter-claims, and cross-claims) alleging that a Contributor Version + directly or indirectly infringes any patent, then the rights granted to + You by any and all Contributors for the Covered Software under Section + 2.1 of this License shall terminate. + +5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user + license agreements (excluding distributors and resellers) which have been + validly granted by You or Your distributors under this License prior to + termination shall survive termination. + +6. Disclaimer of Warranty + + Covered Software is provided under this License on an "as is" basis, + without warranty of any kind, either expressed, implied, or statutory, + including, without limitation, warranties that the Covered Software is free + of defects, merchantable, fit for a particular purpose or non-infringing. + The entire risk as to the quality and performance of the Covered Software + is with You. Should any Covered Software prove defective in any respect, + You (not any Contributor) assume the cost of any necessary servicing, + repair, or correction. This disclaimer of warranty constitutes an essential + part of this License. No use of any Covered Software is authorized under + this License except under this disclaimer. + +7. Limitation of Liability + + Under no circumstances and under no legal theory, whether tort (including + negligence), contract, or otherwise, shall any Contributor, or anyone who + distributes Covered Software as permitted above, be liable to You for any + direct, indirect, special, incidental, or consequential damages of any + character including, without limitation, damages for lost profits, loss of + goodwill, work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses, even if such party shall have been + informed of the possibility of such damages. This limitation of liability + shall not apply to liability for death or personal injury resulting from + such party's negligence to the extent applicable law prohibits such + limitation. Some jurisdictions do not allow the exclusion or limitation of + incidental or consequential damages, so this exclusion and limitation may + not apply to You. + +8. Litigation + + Any litigation relating to this License may be brought only in the courts + of a jurisdiction where the defendant maintains its principal place of + business and such litigation shall be governed by laws of that + jurisdiction, without reference to its conflict-of-law provisions. Nothing + in this Section shall prevent a party's ability to bring cross-claims or + counter-claims. + +9. Miscellaneous + + This License represents the complete agreement concerning the subject + matter hereof. If any provision of this License is held to be + unenforceable, such provision shall be reformed only to the extent + necessary to make it enforceable. Any law or regulation which provides that + the language of a contract shall be construed against the drafter shall not + be used to construe this License against a Contributor. + + +10. Versions of the License + +10.1. New Versions + + Mozilla Foundation is the license steward. Except as provided in Section + 10.3, no one other than the license steward has the right to modify or + publish new versions of this License. Each version will be given a + distinguishing version number. + +10.2. Effect of New Versions + + You may distribute the Covered Software under the terms of the version + of the License under which You originally received the Covered Software, + or under the terms of any subsequent version published by the license + steward. + +10.3. Modified Versions + + If you create software not governed by this License, and you want to + create a new license for such software, you may create and use a + modified version of this License if you rename the license and remove + any references to the name of the license steward (except to note that + such modified license differs from this License). + +10.4. Distributing Source Code Form that is Incompatible With Secondary + Licenses If You choose to distribute Source Code Form that is + Incompatible With Secondary Licenses under the terms of this version of + the License, the notice described in Exhibit B of this License must be + attached. + +Exhibit A - Source Code Form License Notice + + This Source Code Form is subject to the + terms of the Mozilla Public License, v. + 2.0. If a copy of the MPL was not + distributed with this file, You can + obtain one at + http://mozilla.org/MPL/2.0/. + +If it is not possible or desirable to put the notice in a particular file, +then You may include the notice in a location (such as a LICENSE file in a +relevant directory) where a recipient would be likely to look for such a +notice. + +You may add additional accurate notices of copyright ownership. + +Exhibit B - "Incompatible With Secondary Licenses" Notice + + This Source Code Form is "Incompatible + With Secondary Licenses", as defined by + the Mozilla Public License, v. 2.0. + + ======================================================================= END Mozilla Public License, Version 2.0 ======================================================================= @@ -11172,8 +12039,8 @@ END Mozilla Public License, Version 2.0 ===================================================================== END OF NOTICES AND INFORMATION FOR IBM Storage Enabler for -Containers v1.1.1, IBM Storage Kubernetes FlexVolume -v1.1.1, and IBM Storage Kubernetes Dynamic Provisioner -v1.1.1 +Containers Version 1.2, IBM Storage Kubernetes FlexVolume +Version 1.2, IBM Storage Kubernetes Dynamic Provisioner +Version 1.2 ===================================================================== From 9350ac947a35af3e5dd105e34de0e3d4048544fc Mon Sep 17 00:00:00 2001 From: shay-berman Date: Sun, 2 Sep 2018 10:45:20 +0300 Subject: [PATCH 40/40] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 39e17ac67..95d954407 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ This project includes components for managing [Kubernetes persistent storage](ht Currently, the following storage systems use Ubiquity: * IBM block storage. - The IBM block storage is supported for Kubernetes via IBM Spectrum Connect (3.4.0), previously known as IBM Spectrum Control Base Edition. Ubiquity communicates with the IBM storage systems through Spectrum Connect. Spectrum Connect creates a storage profile (for example, gold, silver or bronze) and makes it available for Kubernetes. For details about supported storage systems, refer to the latest Spectrum Connect release notes. + The IBM block storage is supported for Kubernetes via IBM Spectrum Connect. Ubiquity communicates with the IBM storage systems through Spectrum Connect. Spectrum Connect creates a storage profile (for example, gold, silver or bronze) and makes it available for Kubernetes. For details about supported storage systems, refer to the latest Spectrum Connect release notes. The IBM official solution for Kubernetes, based on the Ubiquity project, is referred to as IBM Storage Enabler for Containers. You can download the installation package and its documentation from [IBM Fix Central](https://www.ibm.com/support/fixcentral/swg/selectFixes?parent=Software%2Bdefined%2Bstorage&product=ibm/StorageSoftware/IBM+Spectrum+Connect&release=All&platform=Linux&function=all). For details on the IBM Storage Enabler for Containers, see the relevant sections in the Spectrum Connect user guide.