github.com/sealerio/sealer@v0.11.1-0.20240507115618-f4f89c5853ae/pkg/registry/external.go (about) 1 // Copyright © 2022 Alibaba Group Holding Ltd. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package registry 16 17 import ( 18 "context" 19 "fmt" 20 "net" 21 "os" 22 "strconv" 23 24 "github.com/containers/common/pkg/auth" 25 "github.com/sirupsen/logrus" 26 27 "github.com/sealerio/sealer/common" 28 containerruntime "github.com/sealerio/sealer/pkg/container-runtime" 29 "github.com/sealerio/sealer/pkg/infradriver" 30 v2 "github.com/sealerio/sealer/types/api/v2" 31 ) 32 33 type externalConfigurator struct { 34 containerRuntimeInfo containerruntime.Info 35 infraDriver infradriver.InfraDriver 36 endpoint string 37 username string 38 password string 39 } 40 41 func (e *externalConfigurator) GetRegistryInfo() RegistryInfo { 42 clusterRegistry := e.infraDriver.GetClusterRegistry() 43 return RegistryInfo{ 44 External: clusterRegistry.ExternalRegistry, 45 } 46 } 47 48 func (e *externalConfigurator) InstallOn(masters, nodes []net.IP) error { 49 hosts := append(masters, nodes...) 50 var ( 51 username = e.username 52 password = e.password 53 endpoint = e.endpoint 54 tmpAuthFilePath = "/tmp/config.json" 55 // todo we need this config file when kubelet pull images from registry. while, we could optimize the logic here. 56 remoteKubeletAuthFilePath = "/var/lib/kubelet/config.json" 57 ) 58 59 if username == "" || password == "" { 60 return nil 61 } 62 63 err := auth.Login(context.TODO(), 64 nil, 65 &auth.LoginOptions{ 66 AuthFile: tmpAuthFilePath, 67 Password: password, 68 Username: username, 69 Stdout: os.Stdout, 70 AcceptRepositories: true, 71 }, 72 []string{endpoint}) 73 74 if err != nil { 75 return err 76 } 77 78 defer func() { 79 err = os.Remove(tmpAuthFilePath) 80 if err != nil { 81 logrus.Debugf("failed to remove tmp registry auth file:%s", tmpAuthFilePath) 82 } 83 }() 84 85 err = e.copy2RemoteHosts(tmpAuthFilePath, e.containerRuntimeInfo.ConfigFilePath, hosts) 86 if err != nil { 87 return err 88 } 89 90 err = e.copy2RemoteHosts(tmpAuthFilePath, remoteKubeletAuthFilePath, hosts) 91 if err != nil { 92 return err 93 } 94 95 return nil 96 } 97 98 func (e *externalConfigurator) copy2RemoteHosts(src, dest string, hosts []net.IP) error { 99 f := func(host net.IP) error { 100 err := e.infraDriver.Copy(host, src, dest) 101 if err != nil { 102 return fmt.Errorf("failed to copy local file %s to remote %s : %v", src, dest, err) 103 } 104 return nil 105 } 106 107 return e.infraDriver.Execute(hosts, f) 108 } 109 110 func (e *externalConfigurator) UninstallFrom(masters, nodes []net.IP) error { 111 if e.username == "" || e.password == "" { 112 return nil 113 } 114 hosts := append(masters, nodes...) 115 //todo use sdk to logout instead of shell cmd 116 logoutCmd := fmt.Sprintf("docker logout %s ", e.endpoint) 117 //nolint 118 if e.containerRuntimeInfo.Type != common.Docker { 119 logoutCmd = fmt.Sprintf("nerdctl logout %s ", e.endpoint) 120 } 121 122 for _, host := range hosts { 123 err := e.infraDriver.CmdAsync(host, nil, logoutCmd) 124 if err != nil { 125 return fmt.Errorf("failed to delete registry configuration: %v", err) 126 } 127 } 128 129 return nil 130 } 131 132 func (e *externalConfigurator) GetDriver() (Driver, error) { 133 return newExternalRegistryDriver(e.endpoint), nil 134 } 135 136 func NewExternalConfigurator(regConfig *v2.ExternalRegistry, containerRuntimeInfo containerruntime.Info, driver infradriver.InfraDriver) (Configurator, error) { 137 domain := regConfig.Domain 138 if regConfig.Port != 0 { 139 domain = net.JoinHostPort(regConfig.Domain, strconv.Itoa(regConfig.Port)) 140 } 141 return &externalConfigurator{ 142 endpoint: domain, 143 username: regConfig.Username, 144 password: regConfig.Password, 145 infraDriver: driver, 146 containerRuntimeInfo: containerRuntimeInfo, 147 }, nil 148 }