Re: Newbie questions

"'[email protected]' via help-cfengine" <[email protected]> Mon, 4 Aug 2025 11:58:56 -0700 (PDT)
Newsgroups gmane.comp.sysutils.cfengine.general
Message-ID <[email protected]>
------=_Part_360378_22630295.1754333936843
Content-Type: multipart/alternative; 
	boundary="----=_Part_360379_1736277994.1754333936843"

------=_Part_360379_1736277994.1754333936843
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

Hello Jakub,

Thanks for trying out CFEngine!

I feel your pain when it comes to different, as we call it, WORKDIR values=
=20
e.g. /var/cfengine as we use in our packages versus distribution packages=
=20
which use all kinds of things. Ideally things would "just work" if policy=
=20
and code user the configured WORKDIR value always but this is likely not=20
the case.

Yes, multiline strings are possible, typically using the concat function=20
for comments, strings, etc. For example:

bundle agent main

{

  reports:

"${with}" with =3D> concat(

"hello, ",

"world!");

}

If you find yourself wanting to create "methods bundles" which are "true=20
functions" you might be sort of "doing it wrong" in some ways.

There is a return value mechanism=20
though: https://docs.cfengine.com/docs/3.24/reference-promise-types-methods=
.html#useresult

I would say it is not so often used. Another option I would consider is to=
=20
write a shell script as a wrapper and call that instead.

You had: "my_value" string =3D> do_http_request("some arguments here");

I might suggest: "my_value" string =3D> execresult("wrapper ${arg1}=20
${arg2}",  useshell);

(see https://docs.cfengine.com/docs/3.24/reference-functions-execresult.htm=
l#top)

That way you could use that wrapper in scripts also if need be. Obviously=
=20
you might get into trouble with quotes and spaces going that route but it=
=20
might work for you.

---

A general note at least from my perspective as a member of the CFEngine=20
team and fairly frequent policy writer is if you find yourself trying to=20
write procedural "code", take a minute to refactor things and write policy=
=20
as declarative "what" you want and not so much "how" to make it happen. I=
=20
would even suggest using POSIX sh compatible scripting for some of that=20
"how". Writing procedural style CFEngine policy is possible but in my=20
opinion often leads to policy which is hard to read and debug.

The books suggested so far are great resources.

You might try https://github.com/nickanderson/CFEngine-zero-to-hero-primer=
=20
as well. Nick is a master at policy writing but is out for a few days. He=
=20
will likely have much to say to help you along as well.

Also, there are folks on IRC at libera.chat and Matrix if you like those=20
platforms: https://cfengine.com/developers/ has some more resources.

Keep sending questions, we'll do our best to help you along!

-Craig Comstock
CFEngineer/Digger/Software Engineer
On Monday, August 4, 2025 at 11:28:06=E2=80=AFAM UTC-5 Jakub Wardyn wrote:

> Thank you for your quick responses and suggestions!
>
> I managed to move forward a bit, but there's a lot of "friction".
> Quick try of compiling CFEngine on Alpine Linux failed, so I just settled=
=20
> on the "symlink hack" for now.
> I also know more or less how to hook up to the MPF so it runs my policies=
.
>
> Got quick two questions:
> 1. Can strings in CFEngine be split up into multiline without defining=20
> additional variables, and without adding unintended whitespaces?
> E.g. In C++ I'd do something like this:
> ```
> const char* string =3D "This is my first line,"
> " this is another line";
> ```
> Which evaluates to "This is my first line, this is another line"
> 2. Can I build my own bundles/functions which return values? I've seen=20
> that bundles can modify variables and define class in the parent scope, b=
ut=20
> that seems quite horrible. I mean something like this:
> ```
> vars:
>     "my_value" string =3D> do_http_request("some arguments here");
> ```
> where "do_http_request" is some wrapper around Curl that I can write on m=
y=20
> own,
> can't use url_get, because the binary on Alpine is compiled without curl=
=20
> support, and I would rather not bother with that,
> and instead do what I would do in other languages: abstract the mundane=
=20
> task of calling curl into something less repetitive.
> On Sunday, August 3, 2025 at 7:30:39=E2=80=AFPM UTC+2 brontolinux wrote:
>
>> Hi Jakub=20
>>
>> You need this book: https://cf-learn.info/=20
>>
>> I had the same struggles you have. This book made all the difference.=20
>> Worth every cent.=20
>>
>> Ciao=20
>> -- bronto=20
>>
>> PS: I am in the list of testimonials, but it doesn't mean I earn=20
>> anything if you buy the book or you don't. I do think that Diego's book=
=20
>> is the best CFEngine book ever written.=20
>>
>>

--=20
You received this message because you are subscribed to the Google Groups "=
help-cfengine" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to [email protected].
To view this discussion visit https://groups.google.com/d/msgid/help-cfengi=
ne/ef54b543-15f8-4b23-ad6f-93b574059719n%40googlegroups.com.

------=_Part_360379_1736277994.1754333936843
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

Hello Jakub,<div><br /></div><div>Thanks for trying out CFEngine!</div><div=
><br /></div><div>I feel your pain when it comes to different, as we call i=
t, WORKDIR values e.g. /var/cfengine as we use in our packages versus distr=
ibution packages which use all kinds of things. Ideally things would "just =
work" if policy and code user the configured WORKDIR value always but this =
is likely not the case.</div><div><br /></div><div>Yes, multiline strings a=
re possible, typically using the concat function for comments, strings, etc=
. For example:</div><div><br /></div><div>





<p>bundle agent main</p><p>{</p>
<p>=C2=A0 reports:</p>
<p>"${with}" with =3D&gt; concat(</p>
<p>"hello, ",</p>
<p>"world!");</p>
<p>}</p></div><div><br /></div><div>If you find yourself wanting to create =
"methods bundles" which are "true functions" you might be sort of "doing it=
 wrong" in some ways.</div><div><br /></div><div>There is a return value me=
chanism though:=C2=A0https://docs.cfengine.com/docs/3.24/reference-promise-=
types-methods.html#useresult</div><div><br /></div><div>I would say it is n=
ot so often used. Another option I would consider is to write a shell scrip=
t as a wrapper and call that instead.</div><div><br /></div><div>You had: "=
my_value" string =3D&gt; do_http_request("some arguments here");</div><div>=
<br /></div><div>I might suggest: "my_value" string =3D&gt; execresult("wra=
pper ${arg1} ${arg2}",=C2=A0 useshell);</div><div><br /></div><div>(see=C2=
=A0https://docs.cfengine.com/docs/3.24/reference-functions-execresult.html#=
top)</div><div><br /></div><div>That way you could use that wrapper in scri=
pts also if need be. Obviously you might get into trouble with quotes and s=
paces going that route but it might work for you.</div><div><br /></div><di=
v>---</div><div><br /></div><div>A general note at least from my perspectiv=
e as a member of the CFEngine team and fairly frequent policy writer is if =
you find yourself trying to write procedural "code", take a minute to refac=
tor things and write policy as declarative "what" you want and not so much =
"how" to make it happen. I would even suggest using POSIX sh compatible scr=
ipting for some of that "how". Writing procedural style CFEngine policy is =
possible but in my opinion often leads to policy which is hard to read and =
debug.</div><div><br /></div><div>The books suggested so far are great reso=
urces.</div><div><br /></div><div>You might try=C2=A0https://github.com/nic=
kanderson/CFEngine-zero-to-hero-primer as well. Nick is a master at policy =
writing but is out for a few days. He will likely have much to say to help =
you along as well.</div><div><br /></div><div>Also, there are folks on IRC =
at libera.chat and Matrix if you like those platforms:=C2=A0https://cfengin=
e.com/developers/ has some more resources.</div><div><br /></div><div>Keep =
sending questions, we'll do our best to help you along!</div><div><br /></d=
iv><div>-Craig Comstock</div><div>CFEngineer/Digger/Software Engineer</div>=
<div class=3D"gmail_quote"><div dir=3D"auto" class=3D"gmail_attr">On Monday=
, August 4, 2025 at 11:28:06=E2=80=AFAM UTC-5 Jakub Wardyn wrote:<br/></div=
><blockquote class=3D"gmail_quote" style=3D"margin: 0 0 0 0.8ex; border-lef=
t: 1px solid rgb(204, 204, 204); padding-left: 1ex;">Thank you for your qui=
ck responses and suggestions!<br><br>I managed to move forward a bit, but t=
here&#39;s a lot of &quot;friction&quot;.<br>Quick try of compiling CFEngin=
e on Alpine Linux failed, so I just settled on the &quot;symlink hack&quot;=
 for now.<br>I also know more or less how to hook up to the MPF so it runs =
my policies.<br><br>Got quick two questions:<br>1. Can strings in CFEngine =
be split up into multiline without defining additional variables, and witho=
ut adding unintended whitespaces?<br>E.g. In C++ I&#39;d do something like =
this:<br>```<br>const char* string =3D &quot;This is my first line,&quot;<b=
r>&quot; this is another line&quot;;<br>```<br>Which evaluates to &quot;Thi=
s is my first line, this is another line&quot;<br>2. Can I build my own bun=
dles/functions which return values? I&#39;ve seen that bundles can modify v=
ariables and define class in the parent scope, but that seems quite horribl=
e. I mean something like this:<br>```<br>vars:<br>=C2=A0=C2=A0=C2=A0 &quot;=
my_value&quot; string =3D&gt; do_http_request(&quot;some arguments here&quo=
t;);<br>```<br>where &quot;do_http_request&quot; is some wrapper around Cur=
l that I can write on my own,<br>can&#39;t use url_get, because the binary =
on Alpine is compiled without curl support, and I would rather not bother w=
ith that,<br>and instead do what I would do in other languages: abstract th=
e mundane task of calling curl into something less repetitive.<br><div clas=
s=3D"gmail_quote"><div dir=3D"auto" class=3D"gmail_attr">On Sunday, August =
3, 2025 at 7:30:39=E2=80=AFPM UTC+2 brontolinux wrote:<br></div><blockquote=
 class=3D"gmail_quote" style=3D"margin:0 0 0 0.8ex;border-left:1px solid rg=
b(204,204,204);padding-left:1ex">Hi Jakub
<br>
<br>You need this book: <a href=3D"https://cf-learn.info/" rel=3D"nofollow"=
 target=3D"_blank" data-saferedirecturl=3D"https://www.google.com/url?hl=3D=
en&amp;q=3Dhttps://cf-learn.info/&amp;source=3Dgmail&amp;ust=3D175441919623=
3000&amp;usg=3DAOvVaw3qrHpQE077OdKBsKlkYCGa">https://cf-learn.info/</a>
<br>
<br>I had the same struggles you have. This book made all the difference.=
=20
<br>Worth every cent.
<br>
<br>Ciao
<br>-- bronto
<br>
<br>PS: I am in the list of testimonials, but it doesn&#39;t mean I earn=20
<br>anything if you buy the book or you don&#39;t. I do think that Diego&#3=
9;s book=20
<br>is the best CFEngine book ever written.
<br>
<br></blockquote></div></blockquote></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;help-cfengine&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:[email protected]">help-=
[email protected]</a>.<br />
To view this discussion visit <a href=3D"https://groups.google.com/d/msgid/=
help-cfengine/ef54b543-15f8-4b23-ad6f-93b574059719n%40googlegroups.com?utm_=
medium=3Demail&utm_source=3Dfooter">https://groups.google.com/d/msgid/help-=
cfengine/ef54b543-15f8-4b23-ad6f-93b574059719n%40googlegroups.com</a>.<br /=
>

------=_Part_360379_1736277994.1754333936843--

------=_Part_360378_22630295.1754333936843--