1 |
On 04/06/2016 12:33 PM, Richard Yao wrote: |
2 |
> On 04/06/2016 12:20 PM, Alexis Ballier wrote: |
3 |
>> On Wednesday, April 6, 2016 6:06:35 PM CEST, Richard Yao wrote: |
4 |
>> |
5 |
>>> That is unless you put per-system state in /usr/local, do symlinks to it |
6 |
>>> in / and mount /usr/local as part of system boot, which is the other way |
7 |
>>> of doing this. I have seen a variant of this done in asuswrt-merlin on |
8 |
>>> routers. |
9 |
>> |
10 |
>> This doesnt seem to have anything to do with what I was describing. |
11 |
>> |
12 |
>> Another option I'm using a lot is nfsroot. This doesn't have the same |
13 |
>> level of flexibility: running multiple hosts with nfsroot and thus |
14 |
>> shared /etc/fstab tends to be annoying. |
15 |
>> |
16 |
>>>> See https://fedoraproject.org/wiki/Features/UsrMove for a more complete |
17 |
>>>> discussion. |
18 |
>>> |
19 |
>>> That does not address the problems of supporting this configuration in a |
20 |
>>> rolling release. |
21 |
>>> |
22 |
>>> Formats in /etc can fall out of sync with software in /usr. If boot |
23 |
>>> options change, the stuff in /etc/init.d is not updated. If you add |
24 |
>>> software, the update to /etc/init.d is omitted. If you have a baselayout |
25 |
>>> change, it is not propagated. |
26 |
>> |
27 |
>> Ever heard of CONFIG_PROTECT ? :) What you describe is already what |
28 |
>> happens and what most people want. |
29 |
> |
30 |
> Leveraging the /usr merge to enable easier updating of multiple systems |
31 |
> means that you are updating a Gentoo system image on a build server, |
32 |
> snapshotting /usr both before/after the update and then distributing the |
33 |
> delta on /usr to other systems without any of the changes that occurred |
34 |
> outside of /usr. A proper update requires finding all of those changes |
35 |
> and then applying them manually. That really is not the same thing that |
36 |
> RHEL and Solaris have, where the necessity of propagating changes |
37 |
> outside of /usr is minimized by having none to propagate. |
38 |
|
39 |
After thinking about it some more, maybe git can be (ab)used to do this |
40 |
by having the image's root be a git repository with /usr in .gitingore. |
41 |
|
42 |
When updates are done, you would run etc-update on the build host by |
43 |
committing the changes to / into git with ./usr in .gitignore. Then you |
44 |
would have the delta from /usr via whatever mechanism that the user |
45 |
wishes to use with a patch on / from the build system that can be merged |
46 |
into each target's / repository. The procedure would require more effort |
47 |
than what Solaris and RHEL do, but if documented, it should fix the |
48 |
partial update problem that occurs when you do a /usr merge in a rolling |
49 |
release and then do what people on Solaris and RHEL do to update systems |
50 |
configured for updates via deltas of /usr. |
51 |
|
52 |
To give an example, lets assume: |
53 |
|
54 |
1. /path/to/build/image has a git repository with ./usr in .gitignore on |
55 |
the build host while the targets have the same (with paths being / and |
56 |
/usr of course). |
57 |
|
58 |
2. Things are on ZFS on the build host and the targets. |
59 |
|
60 |
3. There is a snapshot of the build environment that the targets have. |
61 |
|
62 |
4. tank/BUILD/gentoo is the / and tank/BUILD/gentoo/usr is the /usr on |
63 |
the build host. |
64 |
|
65 |
5. The targets have rpool/SYSTEM/USR/gentoo as their /usr and |
66 |
rpool/SYSTEM/USR is set readonly (so /usr is not modified due to |
67 |
inheritance of readonly). |
68 |
|
69 |
The delta generation would be something like this: |
70 |
|
71 |
# Setup build environment |
72 |
sudo -i /path/to/enter-container.sh /path/to/build/image |
73 |
https://gist.github.com/ryao/3c345f206b19c9795109) |
74 |
|
75 |
# Update portage |
76 |
emerge-webrsync / emerge-delta-webrsync / emerge --sync |
77 |
# Preferably one of the first two with PORTAGE_GPG_* configured |
78 |
|
79 |
# Install updates |
80 |
emerge -avDuN @world |
81 |
|
82 |
# Update config files |
83 |
etc-update |
84 |
|
85 |
# Exit build environment |
86 |
exit |
87 |
|
88 |
# Commit changes to / |
89 |
git -C /path/to/build/image commit -a |
90 |
|
91 |
# Snapshot the build environment |
92 |
sudo -i zfs snapshot -r tank/BUILD/gentoo@"$(date +%Y%m%d)" |
93 |
|
94 |
Then a child could be updated by something like: |
95 |
|
96 |
# First /usr |
97 |
zfs send -i tank/BUILD/gentoo@previous tank/BUILD/gentoo/usr@"$(date |
98 |
+%Y%m%d)" | ssh root@$CHILD zfs recv rpool/SYSTEM/USR/gentoo |
99 |
|
100 |
# Then / |
101 |
git -C /path/to/build/image diff HEAD^ | ssh root@$CHILD git -C |
102 |
/other/location apply |
103 |
|
104 |
# If conflicts occurred, fix whatever was broken |
105 |
ssh root@$CHILD |
106 |
|
107 |
# Reboot / restart services |
108 |
reboot |
109 |
|
110 |
This is intended to only be an example, but there are a few problems |
111 |
with this simple example that are worth mentioning: |
112 |
|
113 |
1. You probably want to have a shell into the system in case the update |
114 |
to / does not go well, which makes the update to / somewhat hackish. |
115 |
|
116 |
2. The way Solaris does things is to have boot environments where the |
117 |
change is in a different boot environment that only takes effect as part |
118 |
of a reboot. If you are doing a boot environment type thing, you could |
119 |
probably update / for the new reboot, although you would want to |
120 |
implement easy rollback if anything goes wrong. |
121 |
|
122 |
That step on / is somewhat hackish, but it is intended to be an example. |
123 |
|
124 |
Doing something similar to what Solaris did to make management of |
125 |
multiple systems easier is likely doable with some way of handling |
126 |
changes outside of /usr. |
127 |
|
128 |
> I do not understand how CONFIG_PROTECT is relevant here. Whatever |
129 |
> CONFIG_PROTECT did was done on the build system. The systems receiving |
130 |
> the updates via ZFS send/recv or some similar mechanism are not going to |
131 |
> have CONFIG_PROTECT evaluated. Even if it were somehow evaluated, all of |
132 |
> the paths in CONFIG_PROTECT should be outside of /usr anyway. |