Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

compose: Change /etc/default/useradd to use HOME=/var/home #1726

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
102 changes: 102 additions & 0 deletions rust/src/composepost.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
/*
* Copyright (C) 2018 Red Hat, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/

use failure::Fallible;
use openat;
use std::io::{BufRead, Write};
use std::path::Path;
use std::{fs, io};

/// Helper functions for openat::Dir
trait OpenatDirExt {
// IMO should propose this at least in a "utils" bit of the openat crate;
// Like 95% of the time I'm looking at errno (with files) it's for ENOENT,
// and Rust has an elegant way to map that with Option<>. Every other
// error I usually just want to propagate back up.
fn open_file_optional<P: openat::AsPath>(&self, p: P) -> io::Result<Option<fs::File>>;
}

impl OpenatDirExt for openat::Dir {
fn open_file_optional<P: openat::AsPath>(&self, p: P) -> io::Result<Option<fs::File>> {
match self.open_file(p) {
Ok(f) => Ok(Some(f)),
Err(e) => {
if e.kind() == io::ErrorKind::NotFound {
Ok(None)
} else {
Err(e)
}
}
}
}
}

// rpm-ostree uses /home → /var/home by default as generated by our
// rootfs; we don't expect people to change this. Let's be nice
// and also fixup the $HOME entries generated by `useradd` so
// that `~` shows up as expected in shells, etc.
//
// https://github.com/coreos/fedora-coreos-config/pull/18
// https://pagure.io/workstation-ostree-config/pull-request/121
// https://discussion.fedoraproject.org/t/adapting-user-home-in-etc-passwd/487/6
// https://github.com/justjanne/powerline-go/issues/94
fn postprocess_useradd(rootfs_dfd: &openat::Dir) -> Fallible<()> {
let path = Path::new("usr/etc/default/useradd");
if let Some(f) = rootfs_dfd.open_file_optional(path)? {
let mut f = io::BufReader::new(f);
let tmp_path = path.parent().unwrap().join("useradd.tmp");
let o = rootfs_dfd.write_file(&tmp_path, 0644)?;
let mut bufw = io::BufWriter::new(&o);
for line in f.lines() {
let line = line?;
if !line.starts_with("HOME=") {
bufw.write(line.as_bytes())?;
} else {
bufw.write("HOME=/var/home".as_bytes())?;
}
bufw.write("\n".as_bytes())?;
}
bufw.flush()?;
rootfs_dfd.local_rename(&tmp_path, path)?;
}
Ok(())
}

// This function is called from rpmostree_postprocess_final(); think of
// it as the bits of that function that we've chosen to implement in Rust.
fn compose_postprocess_final(rootfs_dfd: &openat::Dir) -> Fallible<()> {
postprocess_useradd(rootfs_dfd)?;
Ok(())
}

mod ffi {
use super::*;
use ffiutil::*;
use glib_sys;
use libc;

#[no_mangle]
pub extern "C" fn ror_compose_postprocess_final(
rootfs_dfd: libc::c_int,
gerror: *mut *mut glib_sys::GError,
) -> libc::c_int {
let rootfs_dfd = ffi_view_openat_dir(rootfs_dfd);
int_glib_error(compose_postprocess_final(&rootfs_dfd), gerror)
}
}
pub use self::ffi::*;
2 changes: 2 additions & 0 deletions rust/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ mod ffiutil;

mod treefile;
pub use treefile::*;
mod composepost;
pub use composepost::*;
mod progress;
pub use progress::*;
mod journal;
Expand Down
4 changes: 4 additions & 0 deletions src/libpriv/rpmostree-postprocess.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
#include "rpmostree-core.h"
#include "rpmostree-json-parsing.h"
#include "rpmostree-util.h"
#include "rpmostree-rust.h"

typedef enum {
RPMOSTREE_POSTPROCESS_BOOT_LOCATION_BOTH,
Expand Down Expand Up @@ -958,6 +959,9 @@ rpmostree_postprocess_final (int rootfs_dfd,
{
GLNX_AUTO_PREFIX_ERROR ("Finalizing rootfs", error);

if (!ror_compose_postprocess_final (rootfs_dfd, error))
return FALSE;

/* Use installation of the tmpfiles integration as an "idempotence" marker to
* avoid doing postprocessing twice, which can happen when mixing `compose
* postprocess-root` with `compose commit`.
Expand Down
5 changes: 5 additions & 0 deletions tests/compose-tests/libbasic-test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ validate_passwd() {
validate_passwd passwd
validate_passwd group


ostree --repo=${repobuild} cat ${treeref} /usr/etc/default/useradd > useradd.txt
assert_file_has_content_literal useradd.txt HOME=/var/home
echo "ok etc/default/useradd"

for path in /usr/share/rpm /usr/lib/sysimage/rpm-ostree-base-db; do
ostree --repo=${repobuild} ls -R ${treeref} ${path} > db.txt
assert_file_has_content_literal db.txt /Packages
Expand Down