github.com/armen/terraform@v0.5.2-0.20150529052519-caa8117a08f1/builtin/providers/docker/resource_docker_container.go (about) 1 package docker 2 3 import ( 4 "bytes" 5 "fmt" 6 7 "github.com/hashicorp/terraform/helper/hashcode" 8 "github.com/hashicorp/terraform/helper/schema" 9 ) 10 11 func resourceDockerContainer() *schema.Resource { 12 return &schema.Resource{ 13 Create: resourceDockerContainerCreate, 14 Read: resourceDockerContainerRead, 15 Update: resourceDockerContainerUpdate, 16 Delete: resourceDockerContainerDelete, 17 18 Schema: map[string]*schema.Schema{ 19 "name": &schema.Schema{ 20 Type: schema.TypeString, 21 Required: true, 22 ForceNew: true, 23 }, 24 25 // Indicates whether the container must be running. 26 // 27 // An assumption is made that configured containers 28 // should be running; if not, they should not be in 29 // the configuration. Therefore a stopped container 30 // should be started. Set to false to have the 31 // provider leave the container alone. 32 // 33 // Actively-debugged containers are likely to be 34 // stopped and started manually, and Docker has 35 // some provisions for restarting containers that 36 // stop. The utility here comes from the fact that 37 // this will delete and re-create the container 38 // following the principle that the containers 39 // should be pristine when started. 40 "must_run": &schema.Schema{ 41 Type: schema.TypeBool, 42 Default: true, 43 Optional: true, 44 }, 45 46 // ForceNew is not true for image because we need to 47 // sane this against Docker image IDs, as each image 48 // can have multiple names/tags attached do it. 49 "image": &schema.Schema{ 50 Type: schema.TypeString, 51 Required: true, 52 ForceNew: true, 53 }, 54 55 "hostname": &schema.Schema{ 56 Type: schema.TypeString, 57 Optional: true, 58 ForceNew: true, 59 }, 60 61 "domainname": &schema.Schema{ 62 Type: schema.TypeString, 63 Optional: true, 64 ForceNew: true, 65 }, 66 67 "command": &schema.Schema{ 68 Type: schema.TypeList, 69 Optional: true, 70 ForceNew: true, 71 Elem: &schema.Schema{Type: schema.TypeString}, 72 }, 73 74 "dns": &schema.Schema{ 75 Type: schema.TypeSet, 76 Optional: true, 77 ForceNew: true, 78 Elem: &schema.Schema{Type: schema.TypeString}, 79 Set: stringSetHash, 80 }, 81 82 "publish_all_ports": &schema.Schema{ 83 Type: schema.TypeBool, 84 Optional: true, 85 ForceNew: true, 86 }, 87 88 "volumes": &schema.Schema{ 89 Type: schema.TypeSet, 90 Optional: true, 91 ForceNew: true, 92 Elem: getVolumesElem(), 93 Set: resourceDockerVolumesHash, 94 }, 95 96 "ports": &schema.Schema{ 97 Type: schema.TypeSet, 98 Optional: true, 99 ForceNew: true, 100 Elem: getPortsElem(), 101 Set: resourceDockerPortsHash, 102 }, 103 104 "env": &schema.Schema{ 105 Type: schema.TypeSet, 106 Optional: true, 107 ForceNew: true, 108 Elem: &schema.Schema{Type: schema.TypeString}, 109 Set: stringSetHash, 110 }, 111 112 "links": &schema.Schema{ 113 Type: schema.TypeSet, 114 Optional: true, 115 ForceNew: true, 116 Elem: &schema.Schema{Type: schema.TypeString}, 117 Set: stringSetHash, 118 }, 119 120 "ip_address": &schema.Schema{ 121 Type: schema.TypeString, 122 Computed: true, 123 }, 124 125 "ip_prefix_length": &schema.Schema{ 126 Type: schema.TypeInt, 127 Computed: true, 128 }, 129 130 "gateway": &schema.Schema{ 131 Type: schema.TypeString, 132 Computed: true, 133 }, 134 135 "bridge": &schema.Schema{ 136 Type: schema.TypeString, 137 Computed: true, 138 }, 139 }, 140 } 141 } 142 143 func getVolumesElem() *schema.Resource { 144 return &schema.Resource{ 145 Schema: map[string]*schema.Schema{ 146 "from_container": &schema.Schema{ 147 Type: schema.TypeString, 148 Optional: true, 149 ForceNew: true, 150 }, 151 152 "container_path": &schema.Schema{ 153 Type: schema.TypeString, 154 Optional: true, 155 ForceNew: true, 156 }, 157 158 "host_path": &schema.Schema{ 159 Type: schema.TypeString, 160 Optional: true, 161 ForceNew: true, 162 }, 163 164 "read_only": &schema.Schema{ 165 Type: schema.TypeBool, 166 Optional: true, 167 ForceNew: true, 168 }, 169 }, 170 } 171 } 172 173 func getPortsElem() *schema.Resource { 174 return &schema.Resource{ 175 Schema: map[string]*schema.Schema{ 176 "internal": &schema.Schema{ 177 Type: schema.TypeInt, 178 Required: true, 179 ForceNew: true, 180 }, 181 182 "external": &schema.Schema{ 183 Type: schema.TypeInt, 184 Optional: true, 185 ForceNew: true, 186 }, 187 188 "ip": &schema.Schema{ 189 Type: schema.TypeString, 190 Optional: true, 191 ForceNew: true, 192 }, 193 194 "protocol": &schema.Schema{ 195 Type: schema.TypeString, 196 Default: "tcp", 197 Optional: true, 198 ForceNew: true, 199 }, 200 }, 201 } 202 } 203 204 func resourceDockerPortsHash(v interface{}) int { 205 var buf bytes.Buffer 206 m := v.(map[string]interface{}) 207 208 buf.WriteString(fmt.Sprintf("%v-", m["internal"].(int))) 209 210 if v, ok := m["external"]; ok { 211 buf.WriteString(fmt.Sprintf("%v-", v.(int))) 212 } 213 214 if v, ok := m["ip"]; ok { 215 buf.WriteString(fmt.Sprintf("%v-", v.(string))) 216 } 217 218 if v, ok := m["protocol"]; ok { 219 buf.WriteString(fmt.Sprintf("%v-", v.(string))) 220 } 221 222 return hashcode.String(buf.String()) 223 } 224 225 func resourceDockerVolumesHash(v interface{}) int { 226 var buf bytes.Buffer 227 m := v.(map[string]interface{}) 228 229 if v, ok := m["from_container"]; ok { 230 buf.WriteString(fmt.Sprintf("%v-", v.(string))) 231 } 232 233 if v, ok := m["container_path"]; ok { 234 buf.WriteString(fmt.Sprintf("%v-", v.(string))) 235 } 236 237 if v, ok := m["host_path"]; ok { 238 buf.WriteString(fmt.Sprintf("%v-", v.(string))) 239 } 240 241 if v, ok := m["read_only"]; ok { 242 buf.WriteString(fmt.Sprintf("%v-", v.(bool))) 243 } 244 245 return hashcode.String(buf.String()) 246 } 247 248 func stringSetHash(v interface{}) int { 249 return hashcode.String(v.(string)) 250 }