Re: [OE-core] [OE-Core][PATCH] systemd: Default to non-stateless images

2019-05-07 Thread Alex Kiernan
On Mon, May 6, 2019 at 11:28 AM Peter Kjellerstedt
 wrote:
>
> > -Original Message-
> > From: openembedded-core-boun...@lists.openembedded.org  > core-boun...@lists.openembedded.org> On Behalf Of Jonas Bonn
> > Sent: den 6 maj 2019 06:54
> > To: Alex Kiernan ; openembedded-
> > c...@lists.openembedded.org
> > Subject: Re: [OE-core] [OE-Core][PATCH] systemd: Default to non-
> > stateless images
> >
> > Hi Alex,
> >
> > The below is fine and looks good.  The one thing that bothers me about
> > this is that "stateless" isn't really a property of the "distro",
> > rather
> > it's a property of the image/machine.  I suspect, in the same sense
> > that
> > we have readonly-rootfs, that we should probably have image features
> > "stateless-rootfs" (no /etc, no /var) and "volatile-rootfs" (no /var).
> >
> > Furthermore, if you want to boot with 'ro' on the command-line, I
> > really
> > think you need to build your image with the "readonly-rootfs" feature
> > set.  The default should be writable+persistent /etc as that's the
> > configuration used 99% of the time (currently).  "readonly-rootfs" does
> > a bit more than just creating machine-id but it's all relevant to the
> > 'ro' case where /etc isn't writable.
> >
> > Just for clarification:
> >
> > i)  volatile-rootfs:  means there's no point in prepopulating /var
> > because it's on a tmpfs and needs to be populated at boot time
>
> This doesn't really say anything about the state of the rootfs outside
> of /var, i.e., is it writable or read-only?
>
> > ii)  stateless-rootfs:  means there's no point in prepopulating neither
> > /etc nor /var because they are on a tmpfs and need to be populated at
> > boot time
>
> Same here.
>
> > iii)  readonly-rootfs:  means that /etc is really not writable so it's
> > important that: the systemd first-boot stuff needs to be done at build
> > time:  machine-id, unit files set up, all tmpfiles.d snippets that
> > touch /etc and /var need to be done in advance.
> >
> > /Jonas
>
> Maybe we need some more generic way of describing the intended
> structure of the image? E.g., what are the expected behavior of
> /etc, /var and the rest of the rootfs? For each they can typically
> be "read-only", "persistent" (writable and survives reboots) or
> "volatile" (writable, but doesn't survive a reboot).
>

That feels like a useful direction...

Certainly there's constraints in a systemd world as to what's
allowable (which is basically the three models: stateful, volatile and
stateless) - violate those and you end up with all kinds of things you
didn't expect happening (like a new journal being created everytime
you reboot with a new machine id until you run out of disk...)


--
Alex Kiernan
-- 
___
Openembedded-core mailing list
Openembedded-core@lists.openembedded.org
http://lists.openembedded.org/mailman/listinfo/openembedded-core


Re: [OE-core] [OE-Core][PATCH] systemd: Default to non-stateless images

2019-05-06 Thread Alex Kiernan
On Mon, May 6, 2019 at 12:18 PM Jonas Bonn  wrote:
>
> Hi Alex,
>
> On 06/05/2019 11:36, Alex Kiernan wrote:
> > On Mon, May 6, 2019 at 5:54 AM Jonas Bonn  wrote:
> >>
> >> Hi Alex,
> >>
> >> The below is fine and looks good.  The one thing that bothers me about
> >> this is that "stateless" isn't really a property of the "distro", rather
> >> it's a property of the image/machine.
> >
> > I agree it should be part of image, I'll respin it.
> >
> >>   I suspect, in the same sense that
> >> we have readonly-rootfs, that we should probably have image features
> >> "stateless-rootfs" (no /etc, no /var) and "volatile-rootfs" (no /var).
> >>
> >
> > That makes sense to me
> >
> >> Furthermore, if you want to boot with 'ro' on the command-line, I really
> >> think you need to build your image with the "readonly-rootfs" feature
> >> set.  The default should be writable+persistent /etc as that's the
> >> configuration used 99% of the time (currently).  "readonly-rootfs" does
> >> a bit more than just creating machine-id but it's all relevant to the
> >> 'ro' case where /etc isn't writable.
> >>
> >
> > I think there's (at least) two use cases for ro boot:
> >
> > - systems which boot ro and stay that way
> > - systems which transition to rw during systemd-remount-fs
> >
> > I'm in the second case as I have no initramfs and need the filesystem
> > readonly until it's fscked/remounted rw.
>
> I'd argue that you are abusing systemd for this because systemd
> explicity requires /etc to be writable.  The fact that it works on a
> read-only /etc is both incidental and fragile.
>

Not sure... systemd is explicit in its machinery for some parts of
this ro->rw transition (e.g. systemd-machine-id-commit.service),
though it's admittedly silent on what the state of the rest of /etc
is.

> That said, I understand why you want to do this.  Have you considered
> putting the fsck in a "systemd generator" that doesn't return until fsck
> finishes?  Generators are kind of like units that run before systemd
> starts... or, at least, they can be (ab)used in this way.  Systemd won't
> start until all the generators are finished (the idea being that the
> generators may be responsible for creating units dynamically).
>

If systemd comes along and breaks it yes... or I'll teach
ostree-prepare-root how to do it, but right now the sequencing is all
there in systemd.


--
Alex Kiernan
-- 
___
Openembedded-core mailing list
Openembedded-core@lists.openembedded.org
http://lists.openembedded.org/mailman/listinfo/openembedded-core


Re: [OE-core] [OE-Core][PATCH] systemd: Default to non-stateless images

2019-05-06 Thread Jonas Bonn

Hi Alex,

On 06/05/2019 11:36, Alex Kiernan wrote:

On Mon, May 6, 2019 at 5:54 AM Jonas Bonn  wrote:


Hi Alex,

The below is fine and looks good.  The one thing that bothers me about
this is that "stateless" isn't really a property of the "distro", rather
it's a property of the image/machine.


I agree it should be part of image, I'll respin it.


  I suspect, in the same sense that
we have readonly-rootfs, that we should probably have image features
"stateless-rootfs" (no /etc, no /var) and "volatile-rootfs" (no /var).



That makes sense to me


Furthermore, if you want to boot with 'ro' on the command-line, I really
think you need to build your image with the "readonly-rootfs" feature
set.  The default should be writable+persistent /etc as that's the
configuration used 99% of the time (currently).  "readonly-rootfs" does
a bit more than just creating machine-id but it's all relevant to the
'ro' case where /etc isn't writable.



I think there's (at least) two use cases for ro boot:

- systems which boot ro and stay that way
- systems which transition to rw during systemd-remount-fs

I'm in the second case as I have no initramfs and need the filesystem
readonly until it's fscked/remounted rw.


I'd argue that you are abusing systemd for this because systemd 
explicity requires /etc to be writable.  The fact that it works on a 
read-only /etc is both incidental and fragile.


That said, I understand why you want to do this.  Have you considered 
putting the fsck in a "systemd generator" that doesn't return until fsck 
finishes?  Generators are kind of like units that run before systemd 
starts... or, at least, they can be (ab)used in this way.  Systemd won't 
start until all the generators are finished (the idea being that the 
generators may be responsible for creating units dynamically).





Just for clarification:

i)  volatile-rootfs:  means there's no point in prepopulating /var
because it's on a tmpfs and needs to be populated at boot time

ii)  stateless-rootfs:  means there's no point in prepopulating neither
/etc nor /var because they are on a tmpfs and need to be populated at
boot time

iii)  readonly-rootfs:  means that /etc is really not writable so it's
important that: the systemd first-boot stuff needs to be done at build
time:  machine-id, unit files set up, all tmpfiles.d snippets that touch
/etc and /var need to be done in advance.



I'm assuming definitions from here?

http://0pointer.net/blog/projects/stateless.html

Either way, those work for me...


Correct.  Thanks for digging that up... I should have posted it myself.

/Jonas






--
Alex Kiernan


--
___
Openembedded-core mailing list
Openembedded-core@lists.openembedded.org
http://lists.openembedded.org/mailman/listinfo/openembedded-core


Re: [OE-core] [OE-Core][PATCH] systemd: Default to non-stateless images

2019-05-06 Thread Jonas Bonn

Hi Peter,

On 06/05/2019 12:28, Peter Kjellerstedt wrote:

-Original Message-
From: openembedded-core-boun...@lists.openembedded.org  On Behalf Of Jonas Bonn
Sent: den 6 maj 2019 06:54
To: Alex Kiernan ; openembedded-
c...@lists.openembedded.org
Subject: Re: [OE-core] [OE-Core][PATCH] systemd: Default to non-
stateless images

Hi Alex,

The below is fine and looks good.  The one thing that bothers me about
this is that "stateless" isn't really a property of the "distro",
rather
it's a property of the image/machine.  I suspect, in the same sense
that
we have readonly-rootfs, that we should probably have image features
"stateless-rootfs" (no /etc, no /var) and "volatile-rootfs" (no /var).

Furthermore, if you want to boot with 'ro' on the command-line, I
really
think you need to build your image with the "readonly-rootfs" feature
set.  The default should be writable+persistent /etc as that's the
configuration used 99% of the time (currently).  "readonly-rootfs" does
a bit more than just creating machine-id but it's all relevant to the
'ro' case where /etc isn't writable.

Just for clarification:

i)  volatile-rootfs:  means there's no point in prepopulating /var
because it's on a tmpfs and needs to be populated at boot time


This doesn't really say anything about the state of the rootfs outside
of /var, i.e., is it writable or read-only?


ii)  stateless-rootfs:  means there's no point in prepopulating neither
/etc nor /var because they are on a tmpfs and need to be populated at
boot time


Same here.


iii)  readonly-rootfs:  means that /etc is really not writable so it's
important that: the systemd first-boot stuff needs to be done at build
time:  machine-id, unit files set up, all tmpfiles.d snippets that
touch /etc and /var need to be done in advance.

/Jonas


Maybe we need some more generic way of describing the intended
structure of the image? E.g., what are the expected behavior of
/etc, /var and the rest of the rootfs? For each they can typically
be "read-only", "persistent" (writable and survives reboots) or
"volatile" (writable, but doesn't survive a reboot).


Alex already put this link into an earlier response but I'll repeat it 
here and defer to it for the terminology and justification.


http://0pointer.net/blog/projects/stateless.html

That said, the paradigm here is that:

i)  /etc MUST be writable
ii)  /var MUST be writable
iii)  For everything, it doesn't matter... writable or not.  Most 
importantly, though, read-only is OK and no program should assume that 
they can write outside of /etc and /var (and /tmp and /run).


/Jonas



//Peter


--
___
Openembedded-core mailing list
Openembedded-core@lists.openembedded.org
http://lists.openembedded.org/mailman/listinfo/openembedded-core


Re: [OE-core] [OE-Core][PATCH] systemd: Default to non-stateless images

2019-05-06 Thread Peter Kjellerstedt
> -Original Message-
> From: openembedded-core-boun...@lists.openembedded.org  core-boun...@lists.openembedded.org> On Behalf Of Jonas Bonn
> Sent: den 6 maj 2019 06:54
> To: Alex Kiernan ; openembedded-
> c...@lists.openembedded.org
> Subject: Re: [OE-core] [OE-Core][PATCH] systemd: Default to non-
> stateless images
> 
> Hi Alex,
> 
> The below is fine and looks good.  The one thing that bothers me about
> this is that "stateless" isn't really a property of the "distro",
> rather
> it's a property of the image/machine.  I suspect, in the same sense
> that
> we have readonly-rootfs, that we should probably have image features
> "stateless-rootfs" (no /etc, no /var) and "volatile-rootfs" (no /var).
> 
> Furthermore, if you want to boot with 'ro' on the command-line, I
> really
> think you need to build your image with the "readonly-rootfs" feature
> set.  The default should be writable+persistent /etc as that's the
> configuration used 99% of the time (currently).  "readonly-rootfs" does
> a bit more than just creating machine-id but it's all relevant to the
> 'ro' case where /etc isn't writable.
> 
> Just for clarification:
> 
> i)  volatile-rootfs:  means there's no point in prepopulating /var
> because it's on a tmpfs and needs to be populated at boot time

This doesn't really say anything about the state of the rootfs outside 
of /var, i.e., is it writable or read-only?

> ii)  stateless-rootfs:  means there's no point in prepopulating neither
> /etc nor /var because they are on a tmpfs and need to be populated at
> boot time

Same here.

> iii)  readonly-rootfs:  means that /etc is really not writable so it's
> important that: the systemd first-boot stuff needs to be done at build
> time:  machine-id, unit files set up, all tmpfiles.d snippets that
> touch /etc and /var need to be done in advance.
> 
> /Jonas

Maybe we need some more generic way of describing the intended 
structure of the image? E.g., what are the expected behavior of 
/etc, /var and the rest of the rootfs? For each they can typically 
be "read-only", "persistent" (writable and survives reboots) or 
"volatile" (writable, but doesn't survive a reboot).

//Peter

-- 
___
Openembedded-core mailing list
Openembedded-core@lists.openembedded.org
http://lists.openembedded.org/mailman/listinfo/openembedded-core


Re: [OE-core] [OE-Core][PATCH] systemd: Default to non-stateless images

2019-05-06 Thread Alex Kiernan
On Mon, May 6, 2019 at 5:54 AM Jonas Bonn  wrote:
>
> Hi Alex,
>
> The below is fine and looks good.  The one thing that bothers me about
> this is that "stateless" isn't really a property of the "distro", rather
> it's a property of the image/machine.

I agree it should be part of image, I'll respin it.

>  I suspect, in the same sense that
> we have readonly-rootfs, that we should probably have image features
> "stateless-rootfs" (no /etc, no /var) and "volatile-rootfs" (no /var).
>

That makes sense to me

> Furthermore, if you want to boot with 'ro' on the command-line, I really
> think you need to build your image with the "readonly-rootfs" feature
> set.  The default should be writable+persistent /etc as that's the
> configuration used 99% of the time (currently).  "readonly-rootfs" does
> a bit more than just creating machine-id but it's all relevant to the
> 'ro' case where /etc isn't writable.
>

I think there's (at least) two use cases for ro boot:

- systems which boot ro and stay that way
- systems which transition to rw during systemd-remount-fs

I'm in the second case as I have no initramfs and need the filesystem
readonly until it's fscked/remounted rw.

> Just for clarification:
>
> i)  volatile-rootfs:  means there's no point in prepopulating /var
> because it's on a tmpfs and needs to be populated at boot time
>
> ii)  stateless-rootfs:  means there's no point in prepopulating neither
> /etc nor /var because they are on a tmpfs and need to be populated at
> boot time
>
> iii)  readonly-rootfs:  means that /etc is really not writable so it's
> important that: the systemd first-boot stuff needs to be done at build
> time:  machine-id, unit files set up, all tmpfiles.d snippets that touch
> /etc and /var need to be done in advance.
>

I'm assuming definitions from here?

http://0pointer.net/blog/projects/stateless.html

Either way, those work for me...




--
Alex Kiernan
-- 
___
Openembedded-core mailing list
Openembedded-core@lists.openembedded.org
http://lists.openembedded.org/mailman/listinfo/openembedded-core


Re: [OE-core] [OE-Core][PATCH] systemd: Default to non-stateless images

2019-05-05 Thread Jonas Bonn

Hi Alex,

The below is fine and looks good.  The one thing that bothers me about 
this is that "stateless" isn't really a property of the "distro", rather 
it's a property of the image/machine.  I suspect, in the same sense that 
we have readonly-rootfs, that we should probably have image features 
"stateless-rootfs" (no /etc, no /var) and "volatile-rootfs" (no /var).


Furthermore, if you want to boot with 'ro' on the command-line, I really 
think you need to build your image with the "readonly-rootfs" feature 
set.  The default should be writable+persistent /etc as that's the 
configuration used 99% of the time (currently).  "readonly-rootfs" does 
a bit more than just creating machine-id but it's all relevant to the 
'ro' case where /etc isn't writable.


Just for clarification:

i)  volatile-rootfs:  means there's no point in prepopulating /var 
because it's on a tmpfs and needs to be populated at boot time


ii)  stateless-rootfs:  means there's no point in prepopulating neither 
/etc nor /var because they are on a tmpfs and need to be populated at 
boot time


iii)  readonly-rootfs:  means that /etc is really not writable so it's 
important that: the systemd first-boot stuff needs to be done at build 
time:  machine-id, unit files set up, all tmpfiles.d snippets that touch 
/etc and /var need to be done in advance.


/Jonas


On 03/05/2019 18:48, Alex Kiernan wrote:

When creating images, for anything other than the explicitly stateless
case, touch /etc/machine-id so that the images can be booted without an
initramfs and with `ro` set on the kernel command line, otherwise system
refuses to start:

   [7.222134] systemd[1]: No hostname configured.
   [7.227266] systemd[1]: Set hostname to .
   [7.232622] systemd[1]: System cannot boot: Missing /etc/machine-id and 
/etc is mounted read-only.
   [7.241750] systemd[1]: Booting up is supported only when:
   [7.247362] systemd[1]: 1) /etc/machine-id exists and is populated.
   [7.253752] systemd[1]: 2) /etc/machine-id exists and is empty.
   [7.259757] systemd[1]: 3) /etc/machine-id is missing and /etc is 
writable.

If DISTRO_FEATURES includes `stateless` then systemctl-native is not run
on the image leaving the image for population at runtime by systemd.

Signed-off-by: Alex Kiernan 
---

  meta/classes/image.bbclass| 7 +++
  meta/recipes-core/systemd/systemd-systemctl/systemctl | 8 
  2 files changed, 11 insertions(+), 4 deletions(-)

diff --git a/meta/classes/image.bbclass b/meta/classes/image.bbclass
index a23403c0827a..3cb185dd2045 100644
--- a/meta/classes/image.bbclass
+++ b/meta/classes/image.bbclass
@@ -665,12 +665,11 @@ reproducible_final_image_task () {
  fi
  }
  
-IMAGE_EXTRADEPENDS += "${@bb.utils.contains('DISTRO_FEATURES', 'systemd', 'systemd-systemctl-native', '', d)}"

-
  systemd_preset_all () {
-   systemctl --root="${IMAGE_ROOTFS}" --preset-mode=enable-only preset-all
+systemctl --root="${IMAGE_ROOTFS}" --preset-mode=enable-only preset-all
  }
  
-IMAGE_PREPROCESS_COMMAND_append = " ${@bb.utils.contains('DISTRO_FEATURES', 'systemd', 'systemd_preset_all;', '', d)} reproducible_final_image_task; "

+IMAGE_EXTRADEPENDS += "${@ 'systemd-systemctl-native' if 
bb.utils.contains('DISTRO_FEATURES', 'systemd', True, False, d) and not 
bb.utils.contains('DISTRO_FEATURES', 'stateless', True, False, d) else ''}"
+IMAGE_PREPROCESS_COMMAND_append = " ${@ 'systemd_preset_all;' if 
bb.utils.contains('DISTRO_FEATURES', 'systemd', True, False, d) and not 
bb.utils.contains('DISTRO_FEATURES', 'stateless', True, False, d) else ''} 
reproducible_final_image_task; "
  
  CVE_PRODUCT = ""

diff --git a/meta/recipes-core/systemd/systemd-systemctl/systemctl 
b/meta/recipes-core/systemd/systemd-systemctl/systemctl
index d7d4e0d29a09..7da8f23ab893 100755
--- a/meta/recipes-core/systemd/systemd-systemctl/systemctl
+++ b/meta/recipes-core/systemd/systemd-systemctl/systemctl
@@ -241,6 +241,14 @@ def preset_all(root):
  if state == "enable" or state is None:
  enable(root, service, location, services)
  
+# If we populate the systemd links we also create /etc/machine-id, which

+# allows systemd to boot with the filesystem read-only before generating
+# a real value and then committing it back.
+#
+# For the stateless configuration, where /etc is generated at runtime
+# (for example on a tmpfs), this script shouldn't run at all and we
+# allow systemd to completely populate /etc.
+(root / SYSCONFDIR / "machine-id").touch()
  
  def mask(root, *services):

  systemdir = root / SYSCONFDIR / "systemd" / "system"


--
___
Openembedded-core mailing list
Openembedded-core@lists.openembedded.org
http://lists.openembedded.org/mailman/listinfo/openembedded-core


[OE-core] [OE-Core][PATCH] systemd: Default to non-stateless images

2019-05-03 Thread Alex Kiernan
When creating images, for anything other than the explicitly stateless
case, touch /etc/machine-id so that the images can be booted without an
initramfs and with `ro` set on the kernel command line, otherwise system
refuses to start:

  [7.222134] systemd[1]: No hostname configured.
  [7.227266] systemd[1]: Set hostname to .
  [7.232622] systemd[1]: System cannot boot: Missing /etc/machine-id and 
/etc is mounted read-only.
  [7.241750] systemd[1]: Booting up is supported only when:
  [7.247362] systemd[1]: 1) /etc/machine-id exists and is populated.
  [7.253752] systemd[1]: 2) /etc/machine-id exists and is empty.
  [7.259757] systemd[1]: 3) /etc/machine-id is missing and /etc is writable.

If DISTRO_FEATURES includes `stateless` then systemctl-native is not run
on the image leaving the image for population at runtime by systemd.

Signed-off-by: Alex Kiernan 
---

 meta/classes/image.bbclass| 7 +++
 meta/recipes-core/systemd/systemd-systemctl/systemctl | 8 
 2 files changed, 11 insertions(+), 4 deletions(-)

diff --git a/meta/classes/image.bbclass b/meta/classes/image.bbclass
index a23403c0827a..3cb185dd2045 100644
--- a/meta/classes/image.bbclass
+++ b/meta/classes/image.bbclass
@@ -665,12 +665,11 @@ reproducible_final_image_task () {
 fi
 }
 
-IMAGE_EXTRADEPENDS += "${@bb.utils.contains('DISTRO_FEATURES', 'systemd', 
'systemd-systemctl-native', '', d)}"
-
 systemd_preset_all () {
-   systemctl --root="${IMAGE_ROOTFS}" --preset-mode=enable-only preset-all
+systemctl --root="${IMAGE_ROOTFS}" --preset-mode=enable-only preset-all
 }
 
-IMAGE_PREPROCESS_COMMAND_append = " ${@bb.utils.contains('DISTRO_FEATURES', 
'systemd', 'systemd_preset_all;', '', d)} reproducible_final_image_task; "
+IMAGE_EXTRADEPENDS += "${@ 'systemd-systemctl-native' if 
bb.utils.contains('DISTRO_FEATURES', 'systemd', True, False, d) and not 
bb.utils.contains('DISTRO_FEATURES', 'stateless', True, False, d) else ''}"
+IMAGE_PREPROCESS_COMMAND_append = " ${@ 'systemd_preset_all;' if 
bb.utils.contains('DISTRO_FEATURES', 'systemd', True, False, d) and not 
bb.utils.contains('DISTRO_FEATURES', 'stateless', True, False, d) else ''} 
reproducible_final_image_task; "
 
 CVE_PRODUCT = ""
diff --git a/meta/recipes-core/systemd/systemd-systemctl/systemctl 
b/meta/recipes-core/systemd/systemd-systemctl/systemctl
index d7d4e0d29a09..7da8f23ab893 100755
--- a/meta/recipes-core/systemd/systemd-systemctl/systemctl
+++ b/meta/recipes-core/systemd/systemd-systemctl/systemctl
@@ -241,6 +241,14 @@ def preset_all(root):
 if state == "enable" or state is None:
 enable(root, service, location, services)
 
+# If we populate the systemd links we also create /etc/machine-id, which
+# allows systemd to boot with the filesystem read-only before generating
+# a real value and then committing it back.
+#
+# For the stateless configuration, where /etc is generated at runtime
+# (for example on a tmpfs), this script shouldn't run at all and we
+# allow systemd to completely populate /etc.
+(root / SYSCONFDIR / "machine-id").touch()
 
 def mask(root, *services):
 systemdir = root / SYSCONFDIR / "systemd" / "system"
-- 
2.17.1

-- 
___
Openembedded-core mailing list
Openembedded-core@lists.openembedded.org
http://lists.openembedded.org/mailman/listinfo/openembedded-core