lxd/container_metadata.go
func containerMetadataTemplatesGet(d *Daemon, r *http.Request) Response {
	project := projectParam(r)
	name := mux.Vars(r)["name"]

	// Handle requests targeted to a container on a different node
	response, err := ForwardedResponseIfContainerIsRemote(d, r, project, name)
	if err != nil {
		return SmartError(err)
	}
	if response != nil {
		return response
	}

	// Load the container
	c, err := containerLoadByProjectAndName(d.State(), project, name)
	if err != nil {
		return SmartError(err)
	}

	// Start the storage if needed
	ourStart, err := c.StorageStart()
	if err != nil {
		return SmartError(err)
	}
	if ourStart {
		defer c.StorageStop()
	}

	// Look at the request
	templateName := r.FormValue("path")
	if templateName == "" {
		// List templates
		templatesPath := filepath.Join(c.Path(), "templates")
		filesInfo, err := ioutil.ReadDir(templatesPath)
		if err != nil {
			return InternalError(err)
		}

		templates := []string{}
		for _, info := range filesInfo {
			if !info.IsDir() {
				templates = append(templates, info.Name())
			}
		}

		return SyncResponse(true, templates)
	}

	// Check if the template exists
	templatePath, err := getContainerTemplatePath(c, templateName)
	if err != nil {
		return SmartError(err)
	}

	if !shared.PathExists(templatePath) {
		return NotFound(fmt.Errorf("Path '%s' not found", templatePath))
	}

	// Create a temporary file with the template content (since the container
	// storage might not be available when the file is read from FileResponse)
	template, err := os.Open(templatePath)
	if err != nil {
		return SmartError(err)
	}
	defer template.Close()

	tempfile, err := ioutil.TempFile("", "lxd_template")
	if err != nil {
		return SmartError(err)
	}
	defer tempfile.Close()

	_, err = io.Copy(tempfile, template)
	if err != nil {
		return InternalError(err)
	}

	files := make([]fileResponseEntry, 1)
	files[0].identifier = templateName
	files[0].path = tempfile.Name()
	files[0].filename = templateName
	return FileResponse(r, files, nil, true)
}
func containerMetadataTemplatesGet(d *Daemon, r *http.Request) Response {
	project := projectParam(r)
	name := mux.Vars(r)["name"]

	// Handle requests targeted to a container on a different node
	response, err := ForwardedResponseIfContainerIsRemote(d, r, project, name)
	if err != nil {
		return SmartError(err)
	}
	if response != nil {
		return response
	}

	// Load the container
	c, err := containerLoadByProjectAndName(d.State(), project, name)
	if err != nil {
		return SmartError(err)
	}

	// Start the storage if needed
	ourStart, err := c.StorageStart()
	if err != nil {
		return SmartError(err)
	}
	if ourStart {
		defer c.StorageStop()
	}

	// Look at the request
	templateName := r.FormValue("path")
	if templateName == "" {
		// List templates
		templatesPath := filepath.Join(c.Path(), "templates")
		filesInfo, err := ioutil.ReadDir(templatesPath)
		if err != nil {
			return InternalError(err)
		}

		templates := []string{}
		for _, info := range filesInfo {
			if !info.IsDir() {
				templates = append(templates, info.Name())
			}
		}

		return SyncResponse(true, templates)
	}

	// Check if the template exists
	templatePath, err := getContainerTemplatePath(c, templateName)
	if err != nil {
		return SmartError(err)
	}

	if !shared.PathExists(templatePath) {
		return NotFound(fmt.Errorf("Path '%s' not found", templatePath))
	}

	// Create a temporary file with the template content (since the container
	// storage might not be available when the file is read from FileResponse)
	template, err := os.Open(templatePath)
	if err != nil {
		return SmartError(err)
	}
	defer template.Close()

	tempfile, err := ioutil.TempFile("", "lxd_template")
	if err != nil {
		return SmartError(err)
	}
	defer tempfile.Close()

	_, err = io.Copy(tempfile, template)
	if err != nil {
		return InternalError(err)
	}

	files := make([]fileResponseEntry, 1)
	files[0].identifier = templateName
	files[0].path = tempfile.Name()
	files[0].filename = templateName
	return FileResponse(r, files, nil, true)
}
func containerMetadataTemplatesGet ( d * Daemon , r * http . Request ) Response { project := projectParam ( r ) name := mux . Vars ( r ) [ " " ] // Handle requests targeted to a container on a different node response , err := ForwardedResponseIfContainerIsRemote ( d , r , project , name ) if err != nil { return SmartError ( err ) } if response != nil { return response } // Load the container c , err := containerLoadByProjectAndName ( d . State ( ) , project , name ) if err != nil { return SmartError ( err ) } // Start the storage if needed ourStart , err := c . StorageStart ( ) if err != nil { return SmartError ( err ) } if ourStart { defer c . StorageStop ( ) } // Look at the request templateName := r . FormValue ( " " ) if templateName == " " { // List templates templatesPath := filepath . Join ( c . Path ( ) , " " ) filesInfo , err := ioutil . ReadDir ( templatesPath ) if err != nil { return InternalError ( err ) } templates := [ ] string { } for _ , info := range filesInfo { if ! info . IsDir ( ) { templates = append ( templates , info . Name ( ) ) } } return SyncResponse ( true , templates ) } // Check if the template exists templatePath , err := getContainerTemplatePath ( c , templateName ) if err != nil { return SmartError ( err ) } if ! shared . PathExists ( templatePath ) { return NotFound ( fmt . Errorf ( " " , templatePath ) ) } // Create a temporary file with the template content (since the container // storage might not be available when the file is read from FileResponse) template , err := os . Open ( templatePath ) if err != nil { return SmartError ( err ) } defer template . Close ( ) tempfile , err := ioutil . TempFile ( " " , " " ) if err != nil { return SmartError ( err ) } defer tempfile . Close ( ) _ , err = io . Copy ( tempfile , template ) if err != nil { return InternalError ( err ) } files := make ( [ ] fileResponseEntry , 1 ) files [ 0 ] . identifier = templateName files [ 0 ] . path = tempfile . Name ( ) files [ 0 ] . filename = templateName return FileResponse ( r , files , nil , true ) }
// Return a list of templates used in a container or the content of a template
Return a list of templates used in a container or the content of a template