You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: upgrades.go
    path of file: ./repos/juju/provider/vsphere
    
    the code of the file until where you have to start completion: // Copyright 2017 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.

package vsphere

import (
	"path"

	"github.com/juju/errors"
	"github.com/vmware/govmomi/vim25/types"

	"github.com/juju/juju/environs"
	"github.com/juju/juju/environs/context"
	"github.com/juju/juju/environs/tags"
)

// UpgradeOperations is part of the upgrades.OperationSource interface.
func (env *environ) UpgradeOperations(ctx context.ProviderCallContext, args environs.UpgradeOperationsParams) []environs.UpgradeOperation {
	return []environs.UpgradeOperation{{
		TargetVersion: providerVersion1,
		Steps: []environs.UpgradeStep{
			extraConfigUpgradeStep{env, args.ControllerUUID},
			modelFoldersUpgradeStep{env, args.ControllerUUID},
		},
	}}
}

// extraConfigUpgradeStep moves top-level VMs into a model-specific
// VM folder.
type extraConfigUpgradeStep struct {
	env            *environ
	controllerUUID string
}

// Description is part of the environs.UpgradeStep interface.
func (extraConfigUpgradeStep) Description() string {
	return "Update ExtraCo
    
func (step modelFoldersUpgradeStep) Run(ctx context.ProviderCallContext) error {
	return step.env.withSession(ctx, func(env *sessionEnviron) error {
		// We must create the folder even if there are no VMs in the model.
		modelFolderPath := path.Join(env.getVMFolder(), controllerFolderName(step.controllerUUID), env.modelFolderName())

		// EnsureVMFolder needs credential attributes to be defined separately
		// from the folders it is supposed to create
		if _, err := env.client.EnsureVMFolder(
			env.ctx,
			env.getVMFolder(),
			path.Join(controllerFolderName(step.controllerUUID), env.modelFolderName()),
		); err != nil {
			HandleCredentialError(err, env, ctx)
			return errors.Annotate(err, "creating model folder")
		}

		// List all instances at the top level with the model UUID,
		// and move them into the folder.
		vms, err := env.client.VirtualMachines(env.ctx, env.namespace.Prefix()+"*")
		if err != nil || len(vms) == 0 {
			HandleCredentialError(err, env, ctx)
			return err
		}
		refs := make([]types.ManagedObjectReference, len(vms))
		for i, vm := range vms {
			logger.Debugf("moving VM %q into %q", vm.Name, modelFolderPath)
			refs[i] = vm.Reference()
		}
		if err := env.client.MoveVMsInto(env.ctx, modelFolderPath, refs...); err != nil {
			HandleCredentialError(err, env, ctx)
			return errors.Annotate(err, "moving VMs into model folder")
		}
		return nil
	})
}