github.com/vmware/govmomi@v0.43.0/govc/library/sync.go (about) 1 /* 2 Copyright (c) 2019-2024 VMware, Inc. All Rights Reserved. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package library 18 19 import ( 20 "context" 21 "flag" 22 "fmt" 23 24 "github.com/vmware/govmomi/govc/cli" 25 "github.com/vmware/govmomi/govc/flags" 26 "github.com/vmware/govmomi/vapi/library" 27 "github.com/vmware/govmomi/vapi/vcenter" 28 ) 29 30 type sync struct { 31 *flags.FolderFlag 32 *flags.ResourcePoolFlag 33 34 force bool 35 vmtx string 36 } 37 38 func init() { 39 cli.Register("library.sync", &sync{}) 40 } 41 42 func (cmd *sync) Register(ctx context.Context, f *flag.FlagSet) { 43 cmd.FolderFlag, ctx = flags.NewFolderFlag(ctx) 44 cmd.FolderFlag.Register(ctx, f) 45 46 cmd.ResourcePoolFlag, ctx = flags.NewResourcePoolFlag(ctx) 47 cmd.ResourcePoolFlag.Register(ctx, f) 48 49 f.BoolVar(&cmd.force, "f", false, "Forcefully synchronize file content") 50 f.StringVar(&cmd.vmtx, "vmtx", "", "Sync subscribed library to local library as VM Templates") 51 } 52 53 func (cmd *sync) Process(ctx context.Context) error { 54 if err := cmd.FolderFlag.Process(ctx); err != nil { 55 return err 56 } 57 return cmd.ResourcePoolFlag.Process(ctx) 58 } 59 60 func (cmd *sync) Description() string { 61 return `Sync library NAME or ITEM. 62 63 Examples: 64 govc library.sync subscribed-library 65 govc library.sync subscribed-library/item 66 govc library.sync -vmtx local-library subscribed-library # convert subscribed OVFs to local VMTX` 67 } 68 69 func (cmd *sync) Usage() string { 70 return "NAME|ITEM" 71 } 72 73 func (cmd *sync) syncVMTX(ctx context.Context, m *library.Manager, src library.Library, dst library.Library, items ...library.Item) error { 74 if cmd.vmtx == "" { 75 return nil 76 } 77 78 pool, err := cmd.ResourcePool() 79 if err != nil { 80 return err 81 } 82 83 folder, err := cmd.Folder() 84 if err != nil { 85 return err 86 } 87 88 l := vcenter.TemplateLibrary{ 89 Source: src, 90 Destination: dst, 91 Placement: vcenter.Target{ 92 FolderID: folder.Reference().Value, 93 ResourcePoolID: pool.Reference().Value, 94 }, 95 Include: func(item library.Item, current *library.Item) bool { 96 fmt.Printf("Syncing /%s/%s to /%s/%s...", src.Name, item.Name, dst.Name, item.Name) 97 if current == nil { 98 fmt.Println() 99 return true 100 } 101 fmt.Println("already exists.") 102 return false 103 }, 104 } 105 106 return vcenter.NewManager(m.Client).SyncTemplateLibrary(ctx, l, items...) 107 } 108 109 func (cmd *sync) shouldSync(l library.Library) bool { 110 if cmd.vmtx == "" { 111 return true 112 113 } 114 // Allow library.sync -vmtx of LOCAL or SUBSCRIBED library 115 return l.Type == "SUBSCRIBED" 116 } 117 118 func (cmd *sync) Run(ctx context.Context, f *flag.FlagSet) error { 119 if f.NArg() != 1 { 120 return flag.ErrHelp 121 } 122 path := f.Arg(0) 123 124 c, err := cmd.FolderFlag.RestClient() 125 if err != nil { 126 return err 127 } 128 129 m := library.NewManager(c) 130 131 var local library.Library 132 if cmd.vmtx != "" { 133 l, err := flags.ContentLibrary(ctx, c, cmd.vmtx) 134 if err != nil { 135 return err 136 } 137 local = *l 138 } 139 140 res, err := flags.ContentLibraryResult(ctx, c, "", path) 141 if err != nil { 142 return err 143 } 144 145 fmt.Printf("Syncing %s...\n", path) 146 147 switch t := res.GetResult().(type) { 148 case library.Library: 149 if cmd.shouldSync(t) { 150 if err = m.SyncLibrary(ctx, &t); err != nil { 151 return err 152 } 153 } 154 return cmd.syncVMTX(ctx, m, t, local) 155 case library.Item: 156 lib := res.GetParent().GetResult().(library.Library) 157 if cmd.shouldSync(lib) { 158 if err = m.SyncLibraryItem(ctx, &t, cmd.force); err != nil { 159 return err 160 } 161 } 162 return cmd.syncVMTX(ctx, m, lib, local, t) 163 default: 164 return fmt.Errorf("%q is a %T", res.GetPath(), t) 165 } 166 }