171 lines
4 KiB
Perl
171 lines
4 KiB
Perl
# ex:ts=8 sw=4:
|
|
# $OpenBSD: Host.pm,v 1.16 2023/05/06 05:20:31 espie Exp $
|
|
#
|
|
# Copyright (c) 2010-2013 Marc Espie <espie@openbsd.org>
|
|
#
|
|
# Permission to use, copy, modify, and distribute this software for any
|
|
# purpose with or without fee is hereby granted, provided that the above
|
|
# copyright notice and this permission notice appear in all copies.
|
|
#
|
|
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
use v5.36;
|
|
|
|
# we have unique objects for hosts, so we can put properties in there.
|
|
# synopsis
|
|
# $host = DPB::Host->new('name', $prop);
|
|
# then it can be used to obtain a shell to run things
|
|
# ... and also the core class responsible for forking
|
|
# so the full run is usually
|
|
# $core = $host->shellclass->new($host);
|
|
# attach job to core (a job is a list of tasks)
|
|
# $core->task->run;
|
|
# where task knows how to fork, and then it uses
|
|
# $core->host->shell to execute commands
|
|
|
|
# there is a registry of hosts accessible by name:
|
|
# DPB::Host->retrieve(name)
|
|
# a host specific for fetching
|
|
# DPB::Host->fetch_host($prop)
|
|
# a quick way to run shitz before full initialization
|
|
# DPB::Host::Localhost->getshell($state)
|
|
# (this will make use of default_prop/chroot in state
|
|
# if already setup)
|
|
|
|
# actually, the cores are created through host->new_init_core
|
|
# which will start up the initialization for each core
|
|
# and the finalization code will clone and register actual cores
|
|
package DPB::Host;
|
|
|
|
my $hosts = {};
|
|
|
|
sub shell($self)
|
|
{
|
|
# XXX create a lazy shell so host registration already occurred
|
|
$self->{shell} //= $self->shellclass->new($self);
|
|
return $self->{shell};
|
|
}
|
|
|
|
sub create($class, $name, $prop)
|
|
{
|
|
return bless {host => $name, prop => $prop }, $class;
|
|
}
|
|
|
|
sub new($class, $name, $prop = undef)
|
|
{
|
|
if ($class->name_is_localhost($name)) {
|
|
$class = "DPB::Host::Localhost";
|
|
$name = 'localhost';
|
|
} else {
|
|
require DPB::Core::Distant;
|
|
$class = "DPB::Host::Distant";
|
|
$prop->{socket} = "/tmp/ssh-$name-$prop->{master_pid}";
|
|
}
|
|
$hosts->{$name} //= $class->create($name, $prop);
|
|
return $hosts->{$name};
|
|
}
|
|
|
|
sub retrieve($class, $name)
|
|
{
|
|
if ($class->name_is_localhost($name)) {
|
|
return $hosts->{localhost};
|
|
} else {
|
|
return $hosts->{$name};
|
|
}
|
|
}
|
|
|
|
sub fetch_host($class, $prop)
|
|
{
|
|
$hosts->{FETCH} //= DPB::Host::Localhost->create('localhost', $prop);
|
|
return $hosts->{FETCH};
|
|
}
|
|
|
|
sub new_init_core($self)
|
|
{
|
|
return $self->coreclass->new_noreg($self);
|
|
}
|
|
|
|
sub coreclass($)
|
|
{
|
|
return "DPB::Core";
|
|
}
|
|
|
|
sub name($self)
|
|
{
|
|
return $self->{host};
|
|
}
|
|
|
|
sub fullname($self)
|
|
{
|
|
my $name = $self->name;
|
|
if (defined $self->{prop}->{jobs}) {
|
|
$name .= "/$self->{prop}->{jobs}";
|
|
}
|
|
return $name;
|
|
}
|
|
|
|
sub name_is_localhost($class, $host)
|
|
{
|
|
if ($host eq "localhost" or $host eq DPB::Core::Local->hostname) {
|
|
return 1;
|
|
} else {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
package DPB::Host::Localhost;
|
|
our @ISA = qw(DPB::Host);
|
|
|
|
sub create($class, $name, $prop)
|
|
{
|
|
$prop->{iamroot} = $< == 0;
|
|
$prop->{build_user}->enforce_local
|
|
if defined $prop->{build_user};
|
|
return $class->SUPER::create('localhost', $prop);
|
|
}
|
|
|
|
sub is_localhost($)
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
sub is_alive($)
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
|
|
sub shellclass($self)
|
|
{
|
|
if ($self->{prop}{iamroot}) {
|
|
return "DPB::Shell::Local::Root";
|
|
} elsif ($self->{prop}{chroot}) {
|
|
return "DPB::Shell::Local::Chroot";
|
|
} else {
|
|
return "DPB::Shell::Local";
|
|
}
|
|
}
|
|
|
|
# XXX this is a "quicky" local shell before we set up hosts properly
|
|
sub getshell($class, $state)
|
|
{
|
|
my $prop;
|
|
|
|
if ($state->{default_prop}) {
|
|
$prop = $state->{default_prop};
|
|
} else {
|
|
$prop = {};
|
|
if ($state->{chroot}) {
|
|
$prop->{chroot} = $state->{chroot};
|
|
}
|
|
}
|
|
my $h = $class->create('localhost', $prop);
|
|
return $h->shellclass->new($h);
|
|
}
|
|
|
|
1;
|