github.com/richardbowden/terraform@v0.6.12-0.20160901200758-30ea22c25211/builtin/providers/archive/resource_archive_file.go (about)

     1  package archive
     2  
     3  import (
     4  	"crypto/sha1"
     5  	"encoding/hex"
     6  	"fmt"
     7  	"io/ioutil"
     8  	"os"
     9  	"path"
    10  
    11  	"github.com/hashicorp/terraform/helper/schema"
    12  )
    13  
    14  func resourceArchiveFile() *schema.Resource {
    15  	return &schema.Resource{
    16  		Create: resourceArchiveFileCreate,
    17  		Read:   resourceArchiveFileRead,
    18  		Update: resourceArchiveFileUpdate,
    19  		Delete: resourceArchiveFileDelete,
    20  		Exists: resourceArchiveFileExists,
    21  
    22  		Schema: map[string]*schema.Schema{
    23  			"type": &schema.Schema{
    24  				Type:     schema.TypeString,
    25  				Required: true,
    26  				ForceNew: true,
    27  			},
    28  			"source_content": &schema.Schema{
    29  				Type:          schema.TypeString,
    30  				Optional:      true,
    31  				ForceNew:      true,
    32  				ConflictsWith: []string{"source_file", "source_dir"},
    33  			},
    34  			"source_content_filename": &schema.Schema{
    35  				Type:          schema.TypeString,
    36  				Optional:      true,
    37  				ForceNew:      true,
    38  				ConflictsWith: []string{"source_file", "source_dir"},
    39  			},
    40  			"source_file": &schema.Schema{
    41  				Type:          schema.TypeString,
    42  				Optional:      true,
    43  				ForceNew:      true,
    44  				ConflictsWith: []string{"source_content", "source_content_filename", "source_dir"},
    45  			},
    46  			"source_dir": &schema.Schema{
    47  				Type:          schema.TypeString,
    48  				Optional:      true,
    49  				ForceNew:      true,
    50  				ConflictsWith: []string{"source_content", "source_content_filename", "source_file"},
    51  			},
    52  			"output_path": &schema.Schema{
    53  				Type:     schema.TypeString,
    54  				Required: true,
    55  			},
    56  			"output_size": &schema.Schema{
    57  				Type:     schema.TypeInt,
    58  				Computed: true,
    59  				ForceNew: true,
    60  			},
    61  			"output_sha": &schema.Schema{
    62  				Type:        schema.TypeString,
    63  				Computed:    true,
    64  				ForceNew:    true,
    65  				Description: "SHA1 checksum of output file",
    66  			},
    67  		},
    68  	}
    69  }
    70  
    71  func resourceArchiveFileCreate(d *schema.ResourceData, meta interface{}) error {
    72  	if err := resourceArchiveFileUpdate(d, meta); err != nil {
    73  		return err
    74  	}
    75  	return resourceArchiveFileRead(d, meta)
    76  }
    77  
    78  func resourceArchiveFileRead(d *schema.ResourceData, meta interface{}) error {
    79  	outputPath := d.Get("output_path").(string)
    80  	fi, err := os.Stat(outputPath)
    81  	if os.IsNotExist(err) {
    82  		d.SetId("")
    83  		d.MarkNewResource()
    84  		return nil
    85  	}
    86  
    87  	sha, err := genFileSha1(outputPath)
    88  	if err != nil {
    89  		return fmt.Errorf("could not generate file checksum sha: %s", err)
    90  	}
    91  	d.Set("output_sha", sha)
    92  	d.Set("output_size", fi.Size())
    93  	d.SetId(d.Get("output_sha").(string))
    94  
    95  	return nil
    96  }
    97  
    98  func resourceArchiveFileUpdate(d *schema.ResourceData, meta interface{}) error {
    99  	archiveType := d.Get("type").(string)
   100  	outputPath := d.Get("output_path").(string)
   101  
   102  	outputDirectory := path.Dir(outputPath)
   103  	if outputDirectory != "" {
   104  		if _, err := os.Stat(outputDirectory); err != nil {
   105  			if err := os.MkdirAll(outputDirectory, 0777); err != nil {
   106  				return err
   107  			}
   108  		}
   109  	}
   110  
   111  	archiver := getArchiver(archiveType, outputPath)
   112  	if archiver == nil {
   113  		return fmt.Errorf("archive type not supported: %s", archiveType)
   114  	}
   115  
   116  	if dir, ok := d.GetOk("source_dir"); ok {
   117  		if err := archiver.ArchiveDir(dir.(string)); err != nil {
   118  			return fmt.Errorf("error archiving directory: %s", err)
   119  		}
   120  	} else if file, ok := d.GetOk("source_file"); ok {
   121  		if err := archiver.ArchiveFile(file.(string)); err != nil {
   122  			return fmt.Errorf("error archiving file: %s", err)
   123  		}
   124  	} else if filename, ok := d.GetOk("source_content_filename"); ok {
   125  		content := d.Get("source_content").(string)
   126  		if err := archiver.ArchiveContent([]byte(content), filename.(string)); err != nil {
   127  			return fmt.Errorf("error archiving content: %s", err)
   128  		}
   129  	} else {
   130  		return fmt.Errorf("one of 'source_dir', 'source_file', 'source_content_filename' must be specified")
   131  	}
   132  
   133  	// Generate archived file stats
   134  	fi, err := os.Stat(outputPath)
   135  	if err != nil {
   136  		return err
   137  	}
   138  
   139  	sha, err := genFileSha1(outputPath)
   140  	if err != nil {
   141  		return fmt.Errorf("could not generate file checksum sha: %s", err)
   142  	}
   143  	d.Set("output_sha", sha)
   144  	d.Set("output_size", fi.Size())
   145  	d.SetId(d.Get("output_sha").(string))
   146  
   147  	return nil
   148  }
   149  
   150  func resourceArchiveFileDelete(d *schema.ResourceData, meta interface{}) error {
   151  	outputPath := d.Get("output_path").(string)
   152  	if _, err := os.Stat(outputPath); os.IsNotExist(err) {
   153  		return nil
   154  	}
   155  
   156  	if err := os.Remove(outputPath); err != nil {
   157  		return fmt.Errorf("could not delete zip file %q: %s", outputPath, err)
   158  	}
   159  
   160  	return nil
   161  }
   162  
   163  func resourceArchiveFileExists(d *schema.ResourceData, meta interface{}) (bool, error) {
   164  	outputPath := d.Get("output_path").(string)
   165  	_, err := os.Stat(outputPath)
   166  	if os.IsNotExist(err) {
   167  		return false, nil
   168  	}
   169  	if err != nil {
   170  		return false, err
   171  	}
   172  	return true, nil
   173  }
   174  
   175  func genFileSha1(filename string) (string, error) {
   176  	data, err := ioutil.ReadFile(filename)
   177  	if err != nil {
   178  		return "", fmt.Errorf("could not compute file '%s' checksum: %s", filename, err)
   179  	}
   180  	h := sha1.New()
   181  	h.Write([]byte(data))
   182  	return hex.EncodeToString(h.Sum(nil)), nil
   183  }