-
Notifications
You must be signed in to change notification settings - Fork 243
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Adds storage create and delete commands for devfiles. #3626
Adds storage create and delete commands for devfiles. #3626
Conversation
e68b397
to
6888df0
Compare
Codecov Report
@@ Coverage Diff @@
## master #3626 +/- ##
==========================================
- Coverage 44.39% 44.10% -0.29%
==========================================
Files 137 139 +2
Lines 12930 13281 +351
==========================================
+ Hits 5740 5858 +118
- Misses 6629 6853 +224
- Partials 561 570 +9
Continue to review full report at Codecov.
|
4b10eba
to
e8d408f
Compare
3bfc0c7
to
3bdcc67
Compare
/retest |
@@ -128,7 +128,7 @@ func TestGetVolumes(t *testing.T) { | |||
}{ | |||
{ | |||
name: "Case 1: Valid devfile with container referencing a volume component", | |||
component: []versionsCommon.DevfileComponent{testingutil.GetFakeContainerComponent("comp1"), testingutil.GetFakeVolumeComponent("myvolume1")}, | |||
component: []versionsCommon.DevfileComponent{testingutil.GetFakeContainerComponent("comp1"), testingutil.GetFakeVolumeComponent("myvolume1", "4Gi")}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we make a const for 4Gi
value so that it can be changed at only one place if need be and avoid any error if more tests are added?
if component.Container != nil { | ||
for _, volumeMount := range component.Container.VolumeMounts { | ||
if volumeMount.Path == path { | ||
return fmt.Errorf("another volume is mounted on the same path") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should there be more info about which container and path this error showed up for? Would help debug things if someone hits the error, no?
volumeFound = true | ||
} | ||
} | ||
if volumeFound && mountFound { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hope I don't embarass myself with this one, but IIUC, mountFound
and volumeFound
cannot be true
at the same time since they're being set to true
in opposite situations (one in if
and another in else
). Unless we make it:
if component.Volume != nil{
instead of:
else if component.Volume != nil
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
but IIUC, mountFound and volumeFound cannot be true at the same time since they're being set to true in opposite situations (one in if and another in else)
They can be true at the same time too. A component can be a volume or a container. Since we are looping over the components, one can be volume (volumeFound=true) and the other can be a container, which has the volume mounted to it (mountFound=true).
pkg/odo/cli/storage/create.go
Outdated
// Run contains the logic for the odo storage create command | ||
func (o *StorageCreateOptions) Run() (err error) { | ||
storageResult, err := o.LocalConfigInfo.StorageCreate(o.storageName, o.storageSize, o.storagePath) | ||
func (o *StorageCreateOptions) devFileRun() error { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/devFile/devfile
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not a valid camel case word so the GoLand editor's linter keeps complaining. Anyways I have changed it to devfile
.
func (o *StorageCreateOptions) Run() (err error) { | ||
storageResult, err := o.LocalConfigInfo.StorageCreate(o.storageName, o.storageSize, o.storagePath) | ||
func (o *StorageCreateOptions) devFileRun() error { | ||
devFile, err := devfile.ParseAndValidate(o.devfilePath) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same s/devFile/devfile
. I think it's called devfile
. We use Devfile
only when referring to it in beginning of the sentence. That's what I've observed in the docs PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
devfile collides with a package name here, so I kept it to devFile
to avoid confusion.
pkg/odo/cli/storage/create.go
Outdated
storageCreateCmd.Flags().StringVar(&o.devfilePath, "devfile", "./devfile.yaml", "Path to a devfile.yaml") | ||
} | ||
|
||
o.isDevfile = experimental.IsExperimentalModeEnabled() && util.CheckPathExists(o.devfilePath) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't this be the other way round as we move out of experimental mode? I mean, first evaluate o.isDevfile
and then if o.isDevfile
then storageCreateCmd.Flags().StringVar(&o.devfilePath, "devfile", "./devfile.yaml", "Path to a devfile.yaml")
pkg/odo/cli/storage/delete.go
Outdated
storageDeleteCmd.Flags().StringVar(&o.devfilePath, "devfile", "./devfile.yaml", "Path to a devfile.yaml") | ||
} | ||
|
||
o.isDevfile = experimental.IsExperimentalModeEnabled() && util.CheckPathExists(o.devfilePath) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as earlier comment. Shouldn't this be other way round?
@dharmit Fixed. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
while doing odo storage delete
, are we removing volumes from devfile?
Path: path, | ||
}) | ||
} else if component.Volume != nil && component.Volume.Name == volume.Name { | ||
return fmt.Errorf("volume %s already exists", volume.Name) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.
if component.Container != nil { | ||
for _, volumeMount := range component.Container.VolumeMounts { | ||
if volumeMount.Path == path { | ||
return fmt.Errorf("another volume, %s, is mounted to the same path: %s, on the container: %s", volumeMount.Name, path, component.Container.Name) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
VolumeMountError type
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I feel this error is very specific to this function
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/hold
See review
label := "component=" + componentName | ||
PVCs, err := Client.GetPVCsFromSelector(label) | ||
if err != nil { | ||
return errors.Wrapf(err, "Unable to get PVC with selectors "+label) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove capitalization
|
||
// DeleteOldPVCs deletes all the old PVCs which are not in the processedVolumes map | ||
func DeleteOldPVCs(Client *kclient.Client, componentName string, processedVolumes map[string]bool) error { | ||
label := "component=" + componentName |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is kinda weird. Better if we use fmt.Sprinft? Ex. label := fmt.Sprintf("component=%s", componentName)
return errors.Wrapf(err, "Unable to get PVC with selectors "+label) | ||
} | ||
for _, pvc := range PVCs { | ||
storageName, ok := pvc.GetLabels()["storage-name"] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
need to make storage-name
a const
|
||
func (d *Devfile100) DeleteVolume(name string) error { return nil } | ||
|
||
func (d *Devfile100) GetVolumeMountPath(name string) (string, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why not 1 line?
pkg/odo/cli/storage/create.go
Outdated
*genericclioptions.Context | ||
} | ||
|
||
// NewStorageCreateOptions creates a new StorageCreateOptions instance | ||
func NewStorageCreateOptions() *StorageCreateOptions { | ||
return &StorageCreateOptions{} | ||
return &StorageCreateOptions{devfilePath: "./devfile.yaml"} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
devfile.yaml
should be using the const from component
file. In case we were to ever change the name in the future.
pkg/odo/cli/storage/create.go
Outdated
if len(args) != 0 { | ||
o.storageName = args[0] | ||
} else { | ||
o.storageName = o.Component() + "-" + util.GenerateRandomString(4) | ||
o.storageName = o.componentName + "-" + util.GenerateRandomString(4) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
may be better to do fmt.Springf(%s-%d), o.componentName, util.GenerateRandomString(4)
similar to my other comment.
pkg/odo/cli/storage/delete.go
Outdated
*genericclioptions.Context | ||
} | ||
|
||
// NewStorageDeleteOptions creates a new StorageDeleteOptions instance | ||
func NewStorageDeleteOptions() *StorageDeleteOptions { | ||
return &StorageDeleteOptions{} | ||
return &StorageDeleteOptions{devfilePath: "./devfile.yaml"} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
const
pkg/odo/cli/storage/delete.go
Outdated
|
||
o.componentName = o.EnvSpecificInfo.GetName() | ||
} else { | ||
// this initializes the LocalConfigInfo as well |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This
@cdrage Fixed |
/retest |
After creating storage, endpoints in devfile.yaml are populated with invalid data :-(
|
The yaml tags are missing from the devfile endpoint fields in the master branch. I have added them in a new commit. Please have a look. |
/approve |
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: kadel The full list of commands accepted by this bot can be found here. The pull request process is described here
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for making the changes. The code LGTM! Works and tested well.
/lgtm
However... we have no documentation for these new functions.. We should be adding this to some of the Devfile documentation on https://odo.dev
👍 |
What type of PR is this?
/kind feature
What does does this PR do / why we need it:
Adds storage create and delete commands for devfile v2.
Which issue(s) this PR fixes:
part of #3398
fixes #3641
PR acceptance criteria:
Unit test
Integration test
Documentation
How to test changes / Special notes to the reviewer:
Create a devfile component
Create a storage for the component
odo storage create <name> --path <path>
Check if the new volume was added to the devfile and mounted to all the container components.
Execute
odo push
andoc get pvc
and check if the PVC was created or not.Delete the storage
odo storage delete <name> -f
Check the volume is removed from the devfile and unmounted from all the container components.
Execute
odo push
andoc get pvc
and check if the PVC was deleted or not.Try out the json output for the commands.