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 }