github.com/felipejfc/helm@v2.1.2+incompatible/pkg/repo/repotest/server.go (about) 1 /* 2 Copyright 2016 The Kubernetes Authors All rights reserved. 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 16 package repotest 17 18 import ( 19 "io/ioutil" 20 "net/http" 21 "net/http/httptest" 22 "os" 23 "path/filepath" 24 25 "github.com/ghodss/yaml" 26 27 "k8s.io/helm/pkg/repo" 28 ) 29 30 // NewTempServer creates a server inside of a temp dir. 31 // 32 // If the passed in string is not "", it will be treated as a shell glob, and files 33 // will be copied from that path to the server's docroot. 34 // 35 // The caller is responsible for destroying the temp directory as well as stopping 36 // the server. 37 func NewTempServer(glob string) (*Server, string, error) { 38 tdir, err := ioutil.TempDir("", "helm-repotest-") 39 if err != nil { 40 return nil, tdir, err 41 } 42 srv := NewServer(tdir) 43 44 if glob != "" { 45 if _, err := srv.CopyCharts(glob); err != nil { 46 srv.Stop() 47 return srv, tdir, err 48 } 49 } 50 51 return srv, tdir, nil 52 } 53 54 // NewServer creates a repository server for testing. 55 // 56 // docroot should be a temp dir managed by the caller. 57 // 58 // This will start the server, serving files off of the docroot. 59 // 60 // Use CopyCharts to move charts into the repository and then index them 61 // for service. 62 func NewServer(docroot string) *Server { 63 root, err := filepath.Abs(docroot) 64 if err != nil { 65 panic(err) 66 } 67 srv := &Server{ 68 docroot: root, 69 } 70 srv.start() 71 // Add the testing repository as the only repo. 72 if err := setTestingRepository(docroot, "test", srv.URL()); err != nil { 73 panic(err) 74 } 75 return srv 76 } 77 78 // Server is an implementation of a repository server for testing. 79 type Server struct { 80 docroot string 81 srv *httptest.Server 82 } 83 84 // Root gets the docroot for the server. 85 func (s *Server) Root() string { 86 return s.docroot 87 } 88 89 // CopyCharts takes a glob expression and copies those charts to the server root. 90 func (s *Server) CopyCharts(origin string) ([]string, error) { 91 files, err := filepath.Glob(origin) 92 if err != nil { 93 return []string{}, err 94 } 95 copied := make([]string, len(files)) 96 for i, f := range files { 97 base := filepath.Base(f) 98 newname := filepath.Join(s.docroot, base) 99 data, err := ioutil.ReadFile(f) 100 if err != nil { 101 return []string{}, err 102 } 103 if err := ioutil.WriteFile(newname, data, 0755); err != nil { 104 return []string{}, err 105 } 106 copied[i] = newname 107 } 108 109 err = s.CreateIndex() 110 return copied, err 111 } 112 113 // CreateIndex will read docroot and generate an index.yaml file. 114 func (s *Server) CreateIndex() error { 115 // generate the index 116 index, err := repo.IndexDirectory(s.docroot, s.URL()) 117 if err != nil { 118 return err 119 } 120 121 d, err := yaml.Marshal(index) 122 if err != nil { 123 return err 124 } 125 126 ifile := filepath.Join(s.docroot, "index.yaml") 127 return ioutil.WriteFile(ifile, d, 0755) 128 } 129 130 func (s *Server) start() { 131 s.srv = httptest.NewServer(http.FileServer(http.Dir(s.docroot))) 132 } 133 134 // Stop stops the server and closes all connections. 135 // 136 // It should be called explicitly. 137 func (s *Server) Stop() { 138 s.srv.Close() 139 } 140 141 // URL returns the URL of the server. 142 // 143 // Example: 144 // http://localhost:1776 145 func (s *Server) URL() string { 146 return s.srv.URL 147 } 148 149 // LinkIndices links the index created with CreateIndex and makes a symboic link to the repositories/cache directory. 150 // 151 // This makes it possible to simulate a local cache of a repository. 152 func (s *Server) LinkIndices() error { 153 destfile := "test-index.yaml" 154 // Link the index.yaml file to the 155 lstart := filepath.Join(s.docroot, "index.yaml") 156 ldest := filepath.Join(s.docroot, "repository/cache", destfile) 157 return os.Symlink(lstart, ldest) 158 } 159 160 // setTestingRepository sets up a testing repository.yaml with only the given name/URL. 161 func setTestingRepository(helmhome, name, url string) error { 162 rf := repo.NewRepoFile() 163 rf.Add(&repo.Entry{Name: name, URL: url}) 164 os.MkdirAll(filepath.Join(helmhome, "repository", name), 0755) 165 dest := filepath.Join(helmhome, "repository/repositories.yaml") 166 167 return rf.WriteFile(dest, 0644) 168 }