Skip to content

Commit 33c1757

Browse files
feat: support to import some docker_container's attributes (kreuzwerker#234)
1 parent ef47f0c commit 33c1757

File tree

3 files changed

+215
-25
lines changed

3 files changed

+215
-25
lines changed

docker/resource_docker_container.go

+31-2
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ func resourceDockerContainer() *schema.Resource {
114114
Type: schema.TypeString,
115115
Optional: true,
116116
ForceNew: true,
117+
Computed: true,
117118
},
118119

119120
"domainname": {
@@ -126,13 +127,15 @@ func resourceDockerContainer() *schema.Resource {
126127
Type: schema.TypeList,
127128
Optional: true,
128129
ForceNew: true,
130+
Computed: true,
129131
Elem: &schema.Schema{Type: schema.TypeString},
130132
},
131133

132134
"entrypoint": {
133135
Type: schema.TypeList,
134136
Optional: true,
135137
ForceNew: true,
138+
Computed: true,
136139
Elem: &schema.Schema{Type: schema.TypeString},
137140
},
138141

@@ -186,7 +189,7 @@ func resourceDockerContainer() *schema.Resource {
186189
Optional: true,
187190
ForceNew: true,
188191
},
189-
"working_dir": &schema.Schema{
192+
"working_dir": {
190193
Type: schema.TypeString,
191194
Optional: true,
192195
ForceNew: true,
@@ -196,6 +199,7 @@ func resourceDockerContainer() *schema.Resource {
196199
Optional: true,
197200
ForceNew: true,
198201
MaxItems: 1,
202+
// TODO implement DiffSuppressFunc
199203
Elem: &schema.Resource{
200204
Schema: map[string]*schema.Schema{
201205
"add": {
@@ -295,6 +299,7 @@ func resourceDockerContainer() *schema.Resource {
295299
Type: schema.TypeList,
296300
Description: "Optional configuration for the tmpfs type",
297301
Optional: true,
302+
ForceNew: true,
298303
MaxItems: 1,
299304
Elem: &schema.Resource{
300305
Schema: map[string]*schema.Schema{
@@ -452,6 +457,7 @@ func resourceDockerContainer() *schema.Resource {
452457
Type: schema.TypeSet,
453458
Optional: true,
454459
ForceNew: true,
460+
Computed: true,
455461
Elem: &schema.Schema{Type: schema.TypeString},
456462
Set: schema.HashString,
457463
},
@@ -555,6 +561,7 @@ func resourceDockerContainer() *schema.Resource {
555561
Type: schema.TypeSet,
556562
Optional: true,
557563
ForceNew: true,
564+
Computed: true,
558565
Elem: labelSchema,
559566
},
560567

@@ -576,6 +583,7 @@ func resourceDockerContainer() *schema.Resource {
576583
Type: schema.TypeInt,
577584
Optional: true,
578585
ForceNew: true,
586+
Computed: true,
579587
ValidateFunc: validateIntegerGeqThan(0),
580588
},
581589

@@ -620,6 +628,16 @@ func resourceDockerContainer() *schema.Resource {
620628
Type: schema.TypeString,
621629
Optional: true,
622630
ForceNew: true,
631+
DiffSuppressFunc: func(k, oldV, newV string, d *schema.ResourceData) bool {
632+
// treat "" as "default", which is Docker's default value
633+
if oldV == "" {
634+
oldV = "default"
635+
}
636+
if newV == "" {
637+
newV = "default"
638+
}
639+
return oldV == newV
640+
},
623641
},
624642

625643
"networks": {
@@ -763,6 +781,7 @@ func resourceDockerContainer() *schema.Resource {
763781
Description: "IPC sharing mode for the container",
764782
Optional: true,
765783
ForceNew: true,
784+
Computed: true,
766785
},
767786
"group_add": {
768787
Type: schema.TypeSet,
@@ -929,14 +948,24 @@ func resourceDockerContainerV1() *schema.Resource {
929948
ForceNew: true,
930949
Default: "no",
931950
ValidateFunc: validateStringMatchesPattern(`^(no|on-failure|always|unless-stopped)$`),
951+
DiffSuppressFunc: func(k, oldV, newV string, d *schema.ResourceData) bool {
952+
// treat "" as "no", which is Docker's default value
953+
if oldV == "" {
954+
oldV = "no"
955+
}
956+
if newV == "" {
957+
newV = "no"
958+
}
959+
return oldV == newV
960+
},
932961
},
933962

934963
"max_retry_count": {
935964
Type: schema.TypeInt,
936965
Optional: true,
937966
ForceNew: true,
938967
},
939-
"working_dir": &schema.Schema{
968+
"working_dir": {
940969
Type: schema.TypeString,
941970
Optional: true,
942971
ForceNew: true,

docker/resource_docker_container_funcs.go

+146-4
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ func resourceDockerContainerCreate(d *schema.ResourceData, meta interface{}) err
193193
for _, rawTmpfsOptions := range value.([]interface{}) {
194194
rawTmpfsOptions := rawTmpfsOptions.(map[string]interface{})
195195
if value, ok := rawTmpfsOptions["size_bytes"]; ok {
196-
mountInstance.TmpfsOptions.SizeBytes = value.(int64)
196+
mountInstance.TmpfsOptions.SizeBytes = (int64)(value.(int))
197197
}
198198
if value, ok := rawTmpfsOptions["mode"]; ok {
199199
mountInstance.TmpfsOptions.Mode = os.FileMode(value.(int))
@@ -580,9 +580,104 @@ func resourceDockerContainerRead(d *schema.ResourceData, meta interface{}) error
580580

581581
// TODO all the other attributes
582582
d.SetId(container.ID)
583-
// d.Set("name", container.Name) // api prefixes with '/' ...
584-
// d.Set("image", container.Image)
585-
// d.Set("log_driver", container.HostConfig.LogConfig.Type)
583+
d.Set("name", strings.TrimLeft(container.Name, "/")) // api prefixes with '/' ...
584+
d.Set("rm", container.HostConfig.AutoRemove)
585+
d.Set("read_only", container.HostConfig.ReadonlyRootfs)
586+
// "start" can't be imported
587+
// attach
588+
// logs
589+
// "must_run" can't be imported
590+
// container_logs
591+
d.Set("image", container.Image)
592+
d.Set("hostname", container.Config.Hostname)
593+
d.Set("domainname", container.Config.Domainname)
594+
d.Set("command", container.Config.Cmd)
595+
d.Set("entrypoint", container.Config.Entrypoint)
596+
d.Set("user", container.Config.User)
597+
d.Set("dns", container.HostConfig.DNS)
598+
d.Set("dns_opts", container.HostConfig.DNSOptions)
599+
d.Set("dns_search", container.HostConfig.DNSSearch)
600+
d.Set("publish_all_ports", container.HostConfig.PublishAllPorts)
601+
d.Set("restart", container.HostConfig.RestartPolicy.Name)
602+
d.Set("max_retry_count", container.HostConfig.RestartPolicy.MaximumRetryCount)
603+
d.Set("working_dir", container.Config.WorkingDir)
604+
if len(container.HostConfig.CapAdd) > 0 || len(container.HostConfig.CapDrop) > 0 {
605+
// TODO implement DiffSuppressFunc
606+
d.Set("capabilities", []interface{}{
607+
map[string]interface{}{
608+
"add": container.HostConfig.CapAdd,
609+
"drop": container.HostConfig.CapDrop,
610+
},
611+
})
612+
}
613+
d.Set("mounts", getDockerContainerMounts(container))
614+
// volumes
615+
d.Set("tmpfs", container.HostConfig.Tmpfs)
616+
d.Set("host", container.HostConfig.ExtraHosts)
617+
ulimits := make([]interface{}, len(container.HostConfig.Ulimits))
618+
for i, ul := range container.HostConfig.Ulimits {
619+
ulimits[i] = map[string]interface{}{
620+
"name": ul.Name,
621+
"soft": ul.Soft,
622+
"hard": ul.Hard,
623+
}
624+
}
625+
d.Set("ulimit", ulimits)
626+
d.Set("env", container.Config.Env)
627+
d.Set("links", container.HostConfig.Links)
628+
d.Set("privileged", container.HostConfig.Privileged)
629+
devices := make([]interface{}, len(container.HostConfig.Devices))
630+
for i, device := range container.HostConfig.Devices {
631+
devices[i] = map[string]interface{}{
632+
"host_path": device.PathOnHost,
633+
"container_path": device.PathInContainer,
634+
"permissions": device.CgroupPermissions,
635+
}
636+
}
637+
d.Set("devices", devices)
638+
// "destroy_grace_seconds" can't be imported
639+
labels := make([]interface{}, len(container.Config.Labels))
640+
i := 0
641+
for k, v := range container.Config.Labels {
642+
labels[i] = map[string]interface{}{
643+
"label": k,
644+
"value": v,
645+
}
646+
i++
647+
}
648+
d.Set("labels", labels)
649+
d.Set("memory", container.HostConfig.Memory/1024/1024)
650+
if container.HostConfig.MemorySwap > 0 {
651+
d.Set("memory_swap", container.HostConfig.MemorySwap/1024/1024)
652+
} else {
653+
d.Set("memory_swap", container.HostConfig.MemorySwap)
654+
}
655+
d.Set("shm_size", container.HostConfig.ShmSize/1024/1024)
656+
d.Set("cpu_shares", container.HostConfig.CPUShares)
657+
d.Set("cpu_set", container.HostConfig.CpusetCpus)
658+
d.Set("log_driver", container.HostConfig.LogConfig.Type)
659+
d.Set("log_opts", container.HostConfig.LogConfig.Config)
660+
// "network_alias" is deprecated
661+
d.Set("network_mode", container.HostConfig.NetworkMode)
662+
// networks
663+
// networks_advanced
664+
d.Set("pid_mode", container.HostConfig.PidMode)
665+
d.Set("userns_mode", container.HostConfig.UsernsMode)
666+
// "upload" can't be imported
667+
if container.Config.Healthcheck != nil {
668+
d.Set("healthcheck", []interface{}{
669+
map[string]interface{}{
670+
"test": container.Config.Healthcheck.Test,
671+
"interval": container.Config.Healthcheck.Interval.String(),
672+
"timeout": container.Config.Healthcheck.Timeout.String(),
673+
"start_period": container.Config.Healthcheck.StartPeriod.String(),
674+
"retries": container.Config.Healthcheck.Retries,
675+
},
676+
})
677+
}
678+
d.Set("sysctls", container.HostConfig.Sysctls)
679+
d.Set("ipc_mode", container.HostConfig.IpcMode)
680+
d.Set("group_add", container.HostConfig.GroupAdd)
586681
return nil
587682
}
588683

@@ -873,3 +968,50 @@ func deviceSetToDockerDevices(devices *schema.Set) []container.DeviceMapping {
873968
}
874969
return retDevices
875970
}
971+
972+
func getDockerContainerMounts(container types.ContainerJSON) []map[string]interface{} {
973+
mounts := []map[string]interface{}{}
974+
for _, mount := range container.HostConfig.Mounts {
975+
m := map[string]interface{}{
976+
"target": mount.Target,
977+
"source": mount.Source,
978+
"type": mount.Type,
979+
"read_only": mount.ReadOnly,
980+
}
981+
if mount.BindOptions != nil {
982+
m["bind_options"] = []map[string]interface{}{
983+
{
984+
"propagation": mount.BindOptions.Propagation,
985+
},
986+
}
987+
}
988+
if mount.VolumeOptions != nil {
989+
labels := []map[string]string{}
990+
for k, v := range mount.VolumeOptions.Labels {
991+
labels = append(labels, map[string]string{
992+
"label": k,
993+
"volume": v,
994+
})
995+
}
996+
m["volume_options"] = []map[string]interface{}{
997+
{
998+
"no_copy": mount.VolumeOptions.NoCopy,
999+
"labels": labels,
1000+
"driver_name": mount.VolumeOptions.DriverConfig.Name,
1001+
"driver_options": mount.VolumeOptions.DriverConfig.Options,
1002+
},
1003+
}
1004+
}
1005+
if mount.TmpfsOptions != nil {
1006+
m["tmpfs_options"] = []map[string]interface{}{
1007+
{
1008+
"size_bytes": mount.TmpfsOptions.SizeBytes,
1009+
"mode": mount.TmpfsOptions.Mode,
1010+
},
1011+
}
1012+
}
1013+
mounts = append(mounts, m)
1014+
}
1015+
1016+
return mounts
1017+
}

0 commit comments

Comments
 (0)