on fa2bd89 help sign in
docker-hs/src/Docker/Types.hs
313 lines 12 kB history raw
1module Docker.Types where
3import Control.Monad (mzero)
4import Control.Monad.Except (ExceptT, runExceptT)
5import Control.Monad.Reader (ReaderT, runReaderT)
6import Data.Aeson (FromJSON, ToJSON, decode, encode,
7 genericParseJSON, genericToJSON, object,
8 parseJSON, toJSON, (.:), (.=))
9import qualified Data.Aeson as JSON
10import Data.Aeson.Types (defaultOptions, fieldLabelModifier)
11import qualified Data.ByteString.Lazy as BL
12import Data.Char (toUpper)
13import qualified Data.Map as M
14import Data.Text (Text)
15import qualified Data.Text as T
16import GHC.Generics (Generic)
17import qualified Network.HTTP.Client as HTTP
19data Endpoint =
20 VersionEndpoint
21 | ListContainersEndpoint ListOpts
22 | ListImagesEndpoint ListOpts
23 | CreateContainerEndpoint
24 | StartContainerEndpoint ContainerID
25 | StopContainerEndpoint ContainerID
26 | KillContainerEndpoint ContainerID
27 | RestartContainerEndpoint ContainerID
28 | PauseContainerEndpoint ContainerName
29 | UnpauseContainerEndpoint ContainerID
30 | ContainerLogsEndpoint ContainerID LogOpts
31 | DeleteContainerEndpoint ContainerID DeleteOpts
33type URL = Text
34type ApiVersion = Text
35type ContainerID = Text
36type ImageID = Text
37type Timeout = Integer
39type Request = HTTP.Request
40type Response = HTTP.Response BL.ByteString
42data Signal = SIGINT | SIGKILL deriving (Eq, Show)
44data DockerClientOpts = DockerClientOpts {
45 apiVer :: ApiVersion
46 , baseUrl :: URL
47 }
49type HttpHandler m = Request -> m Response
51type DockerT m a = ReaderT (DockerClientOpts, HttpHandler m) (ExceptT String m) a
53runDockerT :: (Monad m) => (DockerClientOpts, HttpHandler m) -> DockerT m a -> m (Either String a)
54runDockerT opts a = runExceptT $ runReaderT a opts
55-- runDockerT opts a = (runExceptT .) . flip runReaderT opts a
57data ListOpts = ListOpts { all :: Bool } deriving (Eq, Show)
59defaultClientOpts :: DockerClientOpts
60defaultClientOpts = DockerClientOpts {
61 apiVer = "v1.22"
62 , baseUrl = "http://127.0.0.1:2375/"
63 }
65data DockerVersion = DockerVersion {
66 version :: Text
67 , apiVersion :: ApiVersion
68 , gitCommit :: Text
69 , goVersion :: Text
70 , os :: Text
71 , arch :: Text
72 , kernelVersion :: Text
73 , buildTime :: Text
74 } deriving (Show, Eq, Generic)
77instance ToJSON DockerVersion where
78 toJSON = genericToJSON defaultOptions {
79 fieldLabelModifier = (\(x:xs) -> toUpper x : xs)}
81instance FromJSON DockerVersion where
82 parseJSON = genericParseJSON defaultOptions {
83 fieldLabelModifier = (\(x:xs) -> toUpper x : xs)}
85data Container = Container
87type Digest = Text
88newtype Labels = Labels (M.Map Name Value) deriving (Eq, Show)
90instance FromJSON Labels where
91 parseJSON val = Labels <$> parseJSON val
93instance ToJSON Labels where
94 toJSON (Labels kvs) = object [k .= v | (k,v) <- (M.toList kvs)]
96type Tag = Text
98data Image = DockerImage {
99 imageId :: ImageID
100 , imageCreated :: Integer
101 , imageParentId :: Maybe ImageID
102 , imageRepoTags :: [Tag]
103 , imageRepoDigests :: [Digest]
104 , imageSize :: Integer
105 , imageVirtualSize :: Integer
106 , imageLabels :: Labels
107 } deriving (Show, Eq, Generic)
109dropImagePrefix = drop 5
111instance FromJSON Image where
112 parseJSON = genericParseJSON defaultOptions {
113 fieldLabelModifier = dropImagePrefix}
115data CreateOpts = CreateOpts
116data StartOpts = StartOpts
118data DeleteOpts = DeleteOpts {
119 deleteVolumes :: Bool
120 , force :: Bool
121 } deriving (Eq, Show)
123type Timestamp = Integer
124data TailLogOpt = Tail Integer | All deriving (Eq, Show)
126data LogOpts = LogOpts {
127 follow :: Bool
128 , stdout :: Bool
129 , stderr :: Bool
130 , since :: Timestamp
131 , timestamps :: Bool
132 , tail :: TailLogOpt
133 } deriving (Eq, Show)
135data VolumePermission = Rw | Ro deriving (Eq, Show, Generic)
137instance ToJSON VolumePermission
138instance FromJSON VolumePermission
140data Volume = Volume { hostSrc :: Text
141 , containerDest :: Text
142 , volumePermission :: Maybe VolumePermission
143 } deriving (Eq, Show)
145data Device = Device {
146 pathOnHost :: FilePath
147 , pathInContainer :: FilePath
148 , cgroupPermissions :: Text
149 } deriving (Eq, Show, Generic)
151instance ToJSON Device where
152 toJSON = genericToJSON defaultOptions {
153 fieldLabelModifier = (\(x:xs) -> toUpper x : xs)}
155instance FromJSON Device where
156 parseJSON = genericParseJSON defaultOptions {
157 fieldLabelModifier = (\(x:xs) -> toUpper x : xs)}
159type ContainerName = Text
161data VolumeFrom = VolumeFrom ContainerName VolumePermission deriving (Eq, Show)
163instance ToJSON Volume where
164 toJSON (Volume src dest mode) = toJSON $ case mode of
165 Nothing -> T.concat[src, ":", dest]
166 Just m -> T.concat[src, ":", dest, ":", (T.pack $ show m)]
168data Link = Link Text (Maybe Text) deriving (Eq, Show)
170instance ToJSON Link where
171 toJSON (Link n1 n2) = toJSON $ case n2 of
172 Nothing -> T.concat[n1, ":", n1]
173 Just n -> T.concat[n1, ":", n]
175-- { "Type": "<driver_name>", "Config": {"key1": "val1"} }
176data LogDriverType = JsonFile | Syslog | Journald | Gelf | AwsLogs | Splunk | LoggingDisabled deriving (Eq, Show)
178data LogDriverOptions = Map Text Text deriving (Eq, Show)
180data LogDriverConfig = LogDriverConfig LogDriverType (Maybe LogDriverOptions) deriving (Eq, Show)
182-- TODO: Add container:<name|id> mode
183data NetworkMode = Bridge | Host | NetworkDisabled deriving (Eq, Show)
185data PortType = TCP | UDP deriving (Eq, Show)
187newtype NetworkInterface = NetworkInterface Text deriving (Eq, Show)
189-- { <port>/<protocol>: [{ "HostPort": "<port>" }] }
190data PortBinding = PortBinding {
191 containerPort :: Integer
192 , portType :: PortType
193 , hostPort :: [HostPort]
194 } deriving (Eq, Show)
196data HostPort = HostPort NetworkInterface Port deriving (Eq, Show)
198-- { "Name": "on-failure" , "MaximumRetryCount": 2}
199type RetryCount = Integer
200data RestartPolicy = RestartAlways | RestartUnlessStopped | RestartOnFailure RetryCount | RestartOff deriving (Eq, Show)
202data Isolation = Default | Process | Hyperv deriving (Eq, Show)
204newtype UTSMode = UTSMode Text deriving (Eq, Show)
206-- TODO: Add Tmpfs : List of tmpfs (mounts) used for the container
207-- TODO: Add UTSMode : UTS namespace to use for the container
208-- TODO: Sysctls map[string]string `json:",omitempty"` // List of Namespaced sysctls used for the container
209data HostConfig = HostConfig
210 { binds :: [Volume]
211 , containerIDFile :: FilePath
212 , logConfig :: LogDriverConfig
213 , networkMode :: NetworkMode
214 , portBindings :: [PortBinding]
215 , restartPolicy :: RestartPolicy
216 , volumeDriver :: Text
217 , volumesFrom :: [VolumeFrom]
218 , capAdd :: [Text]
219 , capDrop :: [Text]
220 , dns :: [Text]
221 , dnsOptions :: [Text]
222 , dnsSearch :: [Text]
223 , extraHosts :: [Text]
224 , groupAdd :: [Integer]
225 , ipcMode :: Text
226 , links :: [Link]
227 , oomScoreAdj :: Integer
228 , pidMode :: Text
229 , privileged :: Bool
230 , publishAllPorts :: Bool
231 , readOnlyRootfs :: Bool
232 , securityOpt :: [Text]
233 , storageOpt :: [Text]
234 , utsMode :: UTSMode
235 , shmSize :: Integer
236 , consoleSize :: Integer
237 , isolation :: Isolation
238 , resources :: ContainerResources
239 } deriving (Eq, Show, Generic)
241-- { "Name": <name>, "Soft": <soft limit>, "Hard": <hard limit> }
242-- { "Name": "nofile", "Soft": 1024, "Hard": 2048 }
243data Ulimit = Ulimit {
244 ulimitName :: Text
245 , ulimitSoft :: Integer
246 , ulimitHard :: Integer
247 } deriving (Eq, Show)
249data ContainerResources = ContainerResources {
250 cpuShares :: Integer
251 , cgroupParent :: Text
252 , blkioWeight :: Text
253 , blkioWeightDevice :: Text
254 , blkioDeviceReadBps :: Text
255 , blkioDeviceWriteBps :: Text
256 , blkioDeviceReadIOps :: Text
257 , blkioDeviceWriteIOps :: Text
258 , cpuPeriod :: Integer
259 , cpuQuota :: Integer
260 , cpusetCpus :: Integer
261 , cpusetMems :: Text
262 , devices :: [Device]
263 , diskQuota :: Integer
264 , kernelMemory :: Integer
265 , memory :: Integer
266 , memoryReservation :: Integer
267 , memorySwap :: Integer
268 , memorySwappiness :: Integer
269 , oomKillDisable :: Bool
270 , pidsLimit :: Integer
271 , ulimits :: [Ulimit]
272 } deriving (Eq, Show)
274type Port = Integer
276type Name = Text
277type Value = Text
279data EnvVar = EnvVar Name Value deriving (Eq, Show)
281data ContainerConfig = ContainerConfig {
282 hostname :: Text
283 , domainname :: Text
284 , user :: Text
285 , attachStdin :: Bool
286 , attachStdout :: Bool
287 , attachStderr :: Bool
288 -- ExposedPorts are used for the PublishAllPorts flag
289 -- to know which ports to publish. Also it's used for
290 -- the deamon to know wich Environment variables to
291 -- inject into a container linking to our container.
292 -- Example linking a Postgres container named db:
293 -- DB_PORT_5432_TCP_PORT="5432"
294 -- DB_PORT_5432_TCP_PROTO="tcp"
295 -- DB_PORT_5432_TCP="tcp://172.17.0.1:5432"
296 , exposedPorts :: [Port]
297 , publishService :: Text
298 , tty :: Bool
299 , openStdin :: Bool
300 , stdinOnce :: Bool
301 , env :: [EnvVar]
302 , cmd :: Text
303 , argsEscaped :: Bool
304 , image :: Text
305 , volumes :: [Volume]
306 , workingDir :: FilePath
307 , entrypoint :: Text
308 , networkDisabled :: Bool
309 , macAddress :: Text
310 , onBuild :: Text
311 , labels :: Labels
312 , stopSignal :: Signal
313 } deriving (Eq, Show)