Skip to content

Commit

Permalink
Name field is guest visible
Browse files Browse the repository at this point in the history
The Name field was changed to be hidden from the guest in vmware#4134 to
support docker rename. This was a compromise needed due to an ESX
vigor bug, see vmware#5533.

This *requires* that users be on a version of ESX that has the fix
or bad things may happen to cVM configurations. I have not tracked
down what build versions that entails and have not code a check
mechanism.

This change has the effect of the hostname of the VCH endpointVM
being set to the name of the VCH.
It also allows additional live reconfiguration such as hotadd to
a bridge network, in general modification of all container
configuration live is possible, if not necessarily applied.
  • Loading branch information
hickeng committed May 13, 2020
1 parent a4a8e9f commit 5f70fbd
Show file tree
Hide file tree
Showing 7 changed files with 244 additions and 2 deletions.
2 changes: 1 addition & 1 deletion lib/config/executor/container_vm.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ type ExecutorConfigCommon struct {
ID string `vic:"0.1" scope:"read-only" key:"id"`

// Convenience field to record a human readable name
Name string `vic:"0.1" scope:"hidden" key:"name"`
Name string `vic:"0.1" scope:"read-only" key:"name"`

// Freeform notes related to the entity
Notes string `vic:"0.1" scope:"hidden" key:"notes"`
Expand Down
9 changes: 9 additions & 0 deletions lib/migration/feature/feature.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,15 @@ const (
// VM folder support for the VCH.
VCHFolderSupportVersion

// Requires minimum ESX patch versions to support live update of guest visible
// fields while VM is running.
// Migrates Name back to guest visible - undoes this specific portion of the
// AddCommonSpecForContainerVersion migration.
// There are two plugin versions because we cannot combine changes to appliance
// and container configs
ContainerGuestVisibleName
ApplianceGuestVisibleName

// Add new feature flag here

// MaxPluginVersion must be the last
Expand Down
1 change: 1 addition & 0 deletions lib/migration/plugins/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,5 @@ import (
_ "github.com/vmware/vic/lib/migration/plugins/plugin7"
_ "github.com/vmware/vic/lib/migration/plugins/plugin8"
_ "github.com/vmware/vic/lib/migration/plugins/plugin9"
_ "github.com/vmware/vic/lib/migration/plugins/plugina"
)
88 changes: 88 additions & 0 deletions lib/migration/plugins/plugina/guest_visible_name_appliance.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
// Copyright 2017 VMware, Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package plugina

import (
"context"
"fmt"

log "github.com/Sirupsen/logrus"

"github.com/vmware/vic/lib/migration/errors"
"github.com/vmware/vic/lib/migration/feature"
"github.com/vmware/vic/lib/migration/manager"
"github.com/vmware/vic/pkg/trace"
"github.com/vmware/vic/pkg/vsphere/extraconfig"
"github.com/vmware/vic/pkg/vsphere/session"
)

const (
atarget = manager.ApplianceConfigure
)

func init() {
defer trace.End(trace.Begin(fmt.Sprintf("Registering plugins %s:%d", atarget, feature.ApplianceGuestVisibleName)))

if err := manager.Migrator.Register(feature.ApplianceGuestVisibleName, atarget, &ApplianceGuestVisibleName{}); err != nil {
log.Errorf("Failed to register plugin %s:%d, %s", atarget, feature.ApplianceGuestVisibleName, err)
panic(err)
}
}

// VCHGuestVisibleName is plugin for vic 1.5.6 version upgrade
type ApplianceGuestVisibleName struct {
}

// Migrate is almost identical to the Migrate for containers, but with the UpdatedExecutorConfig nested into
// the VCH config. This could likely be avoid using extraconfig.DecodeWithPrefix but I chose to follow the
// pattern from prior plugins.
func (p *ApplianceGuestVisibleName) Migrate(ctx context.Context, s *session.Session, data interface{}) error {
defer trace.End(trace.Begin(fmt.Sprintf("ApplianceGuestVisibleName version: %d", feature.ApplianceGuestVisibleName)))
if data == nil {
return nil
}
mapData, ok := data.(map[string]string)
if !ok {
// Log the error here and return nil so that other plugins can proceed
log.Errorf("Migration data format is not map: %+v", data)
return nil
}
oldStruct := &VirtualContainerHostConfigSpec{}
result := extraconfig.Decode(extraconfig.MapSource(mapData), oldStruct)
log.Debugf("The oldStruct is %+v", oldStruct)
if result == nil {
return &errors.DecodeError{Err: fmt.Errorf("decode oldStruct %+v failed", oldStruct)}
}

newStruct := &UpdatedVCHConfigSpec{
UpdatedExecutorConfig: UpdatedExecutorConfig{
UpdatedCommon: UpdatedCommon{
Name: oldStruct.Name,
ID: oldStruct.ID,
ExecutionEnvironment: oldStruct.ExecutionEnvironment,
Notes: oldStruct.Notes,
},
},
}

cfg := make(map[string]string)
extraconfig.Encode(extraconfig.MapSink(cfg), newStruct)

for k, v := range cfg {
log.Debugf("New data: %s:%s", k, v)
mapData[k] = v
}
return nil
}
83 changes: 83 additions & 0 deletions lib/migration/plugins/plugina/guest_visible_name_container.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
// Copyright 2017 VMware, Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package plugina

import (
"context"
"fmt"

log "github.com/Sirupsen/logrus"

"github.com/vmware/vic/lib/migration/errors"
"github.com/vmware/vic/lib/migration/feature"
"github.com/vmware/vic/lib/migration/manager"
"github.com/vmware/vic/pkg/trace"
"github.com/vmware/vic/pkg/vsphere/extraconfig"
"github.com/vmware/vic/pkg/vsphere/session"
)

const (
ctarget = manager.ContainerConfigure
)

func init() {
defer trace.End(trace.Begin(fmt.Sprintf("Registering plugins %s:%d", ctarget, feature.ContainerGuestVisibleName)))

if err := manager.Migrator.Register(feature.ContainerGuestVisibleName, ctarget, &ContainerGuestVisibleName{}); err != nil {
log.Errorf("Failed to register plugin %s:%d, %s", ctarget, feature.ContainerGuestVisibleName, err)
panic(err)
}
}

// ContainerGuestVisibleName is plugin for vic 1.5.6 version upgrade
type ContainerGuestVisibleName struct {
}

// Migrate deals with the container config and is distinct from the Migrate which is for VCH config.
func (p *ContainerGuestVisibleName) Migrate(ctx context.Context, s *session.Session, data interface{}) error {
defer trace.End(trace.Begin(fmt.Sprintf("ContainerGuestVisibleName version %d", feature.ContainerGuestVisibleName)))
if data == nil {
return nil
}
mapData, ok := data.(map[string]string)
if !ok {
// Log the error here and return nil so that other plugins can proceed
log.Errorf("Migration data format is not map: %+v", data)
return nil
}
oldStruct := &ExecutorConfig{}
result := extraconfig.Decode(extraconfig.MapSource(mapData), oldStruct)
log.Debugf("The oldStruct is %+v", oldStruct)
if result == nil {
return &errors.DecodeError{Err: fmt.Errorf("decode oldStruct %+v failed", oldStruct)}
}

newStruct := &UpdatedExecutorConfig{
UpdatedCommon: UpdatedCommon{
Name: oldStruct.Name,
ID: oldStruct.ID,
Notes: oldStruct.Notes,
ExecutionEnvironment: oldStruct.ExecutionEnvironment,
}}

cfg := make(map[string]string)
extraconfig.Encode(extraconfig.MapSink(cfg), newStruct)

for k, v := range cfg {
log.Debugf("New data: %s:%s", k, v)
mapData[k] = v
}
return nil
}
59 changes: 59 additions & 0 deletions lib/migration/plugins/plugina/types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// Copyright 2017 VMware, Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package plugina

type ExecutorConfig struct {
Common `vic:"0.1" scope:"read-only" key:"common"`
}

type Common struct {
// A reference to the components hosting execution environment, if any
ExecutionEnvironment string

// Unambiguous ID with meaning in the context of its hosting execution environment
ID string `vic:"0.1" scope:"read-only" key:"id"`

// Convenience field to record a human readable name
Name string `vic:"0.1" scope:"hidden" key:"name"`

// Freeform notes related to the entity
Notes string `vic:"0.1" scope:"hidden" key:"notes"`
}

type UpdatedCommon struct {
// A reference to the components hosting execution environment, if any
ExecutionEnvironment string

// Unambiguous ID with meaning in the context of its hosting execution environment
ID string `vic:"0.1" scope:"read-only" key:"id"`

// Convenience field to record a human readable name
Name string `vic:"0.1" scope:"read-only" key:"name"`

// Freeform notes related to the entity
Notes string `vic:"0.1" scope:"hidden" key:"notes"`
}

type VirtualContainerHostConfigSpec struct {
ExecutorConfig `vic:"0.1" scope:"read-only" key:"init"`
}

type UpdatedVCHConfigSpec struct {
UpdatedExecutorConfig `vic:"0.1" scope:"read-only" key:"init"`
}

type UpdatedExecutorConfig struct {
UpdatedCommon `vic:"0.1" scope:"read-only" key:"common"`
}
4 changes: 3 additions & 1 deletion lib/portlayer/exec/handle.go
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,9 @@ func (h *Handle) Commit(op trace.Operation, sess *session.Session, waitTime *int
// any values set with VM powered off are inherently persistent
filter = ^extraconfig.NonPersistent
} else {
filter = extraconfig.NonPersistent | extraconfig.Hidden
// API side changes should no longer convert persistent keys to non-persistent while VM is running
// allow write of everything
filter = ^0
}

extraconfig.Encode(extraconfig.ScopeFilterSink(uint(filter), extraconfig.MapSink(cfg)), h.ExecConfig)
Expand Down

0 comments on commit 5f70fbd

Please sign in to comment.