Hello Joey,
I try to setup a debomatic service on one of my computer. So I created a data which will store on which host it was installed
data DebOMaticHostMirror = DebOMaticHostMirror Url
deriving (Eq, Show, Typeable)
So now I try to create a property which get the hostname and set the info, BUT I did not find the right way to do this. Here an attempt
debomaticHostMirror :: Property (HasInfo + UnixLike)
debomaticHostMirror = property' desc $ \w -> do
hostname <- asks hostName
ensureProperty $ pureInfoProperty desc (InfoVal (DebOMaticHostMirror hostname))
where
desc = "setup the Deb-O-Matic host name for other properties"
but I get this error message
src/propellor-config.hs:935:3: error:
• Couldn't match expected type ‘Propellor Result’
with actual type ‘Property
(Propellor.Types.MetaTypes.MetaTypes inner0)
-> Propellor Result’
• In a stmt of a 'do' block:
ensureProperty
$ pureInfoProperty desc (InfoVal (DebOMaticHostMirror hostname))
In the expression:
do { hostname <- asks hostName;
ensureProperty
$ pureInfoProperty desc (InfoVal (DebOMaticHostMirror hostname)) }
In the second argument of ‘($)’, namely
‘\ w
-> do { hostname <- asks hostName;
ensureProperty
$ pureInfoProperty desc (InfoVal (DebOMaticHostMirror hostname)) }’
src/propellor-config.hs:935:20: error:
• Couldn't match expected type ‘OuterMetaTypesWitness outer0’
with actual type ‘Property (HasInfo + UnixLike)’
• In the second argument of ‘($)’, namely
‘pureInfoProperty desc (InfoVal (DebOMaticHostMirror hostname))’
In a stmt of a 'do' block:
ensureProperty
$ pureInfoProperty desc (InfoVal (DebOMaticHostMirror hostname))
In the expression:
do { hostname <- asks hostName;
ensureProperty
$ pureInfoProperty desc (InfoVal (DebOMaticHostMirror hostname)) }
the Idea after is to create a property which will take the DeboMatic Info and generate the /etc/apt/sourses.list.d/debomatic.list on a bunch of hosts.
Maybe we could have a
typeclass Mirror a where
toSourceListDLines :: a -> [Line]
instance Mirror DebOMaticHostMirror where
toSourceListDLines (DebOMaticHostMirror hostname) = ...
then the stdSourceListD property should be change to use toSourceListDLines
but this is another story
It's not allowed for the content of Info to come from an IO action. Info has to be static. This allows one Host to introspect the Info of another Host. The Dns properties rely on that.
So, the type checker is right in preventing this. It's also not allowed to use ensureProperty with a property that HasInfo, as the info would not propigate to the outer property. The type checker is also preventing you making that mistake.
(You also forgot to pass the
w
parameter toensureProperty
, which made the type checker unhappy as well and probably confused the error messages.)To accomplish your goal, you could use:
If a Host has this in its Info, you know that Host is the one with debomatic installed. You can then get its hostname using the
hostName
field accessor on the Host.The property that does that will need to be passed a
[Host]
which will typically be thehosts
list defined in config.hs.I could have multiple host with debomatic install on it. I need to create a property which take a list of hosts (all with the Debomatic info) in order to generate the sources.list files. This way it is possible for me to select per host the sources of packages.
what should be done in order to type check this ? I would like the compiler to says. Hey you ask for a source list from this host but it dos not contain a Debian mirror.
Cheers
Finding a way to type check that, I don't know. It would certianly be nice to be able to statically check such things. The way that Info is implemented as a monoid that contains many different types seems to preclude exposing enough information for the type checker to catch such a problem. So it would have to be changed somehow, I don't know how.