github.com/tarrant/terraform@v0.3.8-0.20150402012457-f68c9eee638e/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  	}
   113  }
   114  
   115  func getVolumesElem() *schema.Resource {
   116  	return &schema.Resource{
   117  		Schema: map[string]*schema.Schema{
   118  			"from_container": &schema.Schema{
   119  				Type:     schema.TypeString,
   120  				Optional: true,
   121  				ForceNew: true,
   122  			},
   123  
   124  			"container_path": &schema.Schema{
   125  				Type:     schema.TypeString,
   126  				Optional: true,
   127  				ForceNew: true,
   128  			},
   129  
   130  			"host_path": &schema.Schema{
   131  				Type:     schema.TypeString,
   132  				Optional: true,
   133  				ForceNew: true,
   134  			},
   135  
   136  			"read_only": &schema.Schema{
   137  				Type:     schema.TypeBool,
   138  				Optional: true,
   139  				ForceNew: true,
   140  			},
   141  		},
   142  	}
   143  }
   144  
   145  func getPortsElem() *schema.Resource {
   146  	return &schema.Resource{
   147  		Schema: map[string]*schema.Schema{
   148  			"internal": &schema.Schema{
   149  				Type:     schema.TypeInt,
   150  				Required: true,
   151  				ForceNew: true,
   152  			},
   153  
   154  			"external": &schema.Schema{
   155  				Type:     schema.TypeInt,
   156  				Optional: true,
   157  				ForceNew: true,
   158  			},
   159  
   160  			"ip": &schema.Schema{
   161  				Type:     schema.TypeString,
   162  				Optional: true,
   163  				ForceNew: true,
   164  			},
   165  
   166  			"protocol": &schema.Schema{
   167  				Type:     schema.TypeString,
   168  				Default:  "tcp",
   169  				Optional: true,
   170  				ForceNew: true,
   171  			},
   172  		},
   173  	}
   174  }
   175  
   176  func resourceDockerPortsHash(v interface{}) int {
   177  	var buf bytes.Buffer
   178  	m := v.(map[string]interface{})
   179  
   180  	buf.WriteString(fmt.Sprintf("%v-", m["internal"].(int)))
   181  
   182  	if v, ok := m["external"]; ok {
   183  		buf.WriteString(fmt.Sprintf("%v-", v.(int)))
   184  	}
   185  
   186  	if v, ok := m["ip"]; ok {
   187  		buf.WriteString(fmt.Sprintf("%v-", v.(string)))
   188  	}
   189  
   190  	if v, ok := m["protocol"]; ok {
   191  		buf.WriteString(fmt.Sprintf("%v-", v.(string)))
   192  	}
   193  
   194  	return hashcode.String(buf.String())
   195  }
   196  
   197  func resourceDockerVolumesHash(v interface{}) int {
   198  	var buf bytes.Buffer
   199  	m := v.(map[string]interface{})
   200  
   201  	if v, ok := m["from_container"]; ok {
   202  		buf.WriteString(fmt.Sprintf("%v-", v.(string)))
   203  	}
   204  
   205  	if v, ok := m["container_path"]; ok {
   206  		buf.WriteString(fmt.Sprintf("%v-", v.(string)))
   207  	}
   208  
   209  	if v, ok := m["host_path"]; ok {
   210  		buf.WriteString(fmt.Sprintf("%v-", v.(string)))
   211  	}
   212  
   213  	if v, ok := m["read_only"]; ok {
   214  		buf.WriteString(fmt.Sprintf("%v-", v.(bool)))
   215  	}
   216  
   217  	return hashcode.String(buf.String())
   218  }
   219  
   220  func stringSetHash(v interface{}) int {
   221  	return hashcode.String(v.(string))
   222  }