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  }