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