blob: 20ec94caf790fc4293e7ca901459618b42b07e35 [file] [log] [blame]
#!/usr/bin/perl -w
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
##############################################################################
# $Id: Linux.pm 1945 2008-12-11 20:58:08Z fapeeler $
##############################################################################
=head1 NAME
VCL::Module::OS::Linux.pm - VCL module to support Linux operating systems
=head1 SYNOPSIS
Needs to be written
=head1 DESCRIPTION
This module provides VCL support for Linux operating systems.
=cut
##############################################################################
package VCL::Module::OS::Linux;
# Specify the lib path using FindBin
use FindBin;
use lib "$FindBin::Bin/../../..";
# Configure inheritance
use base qw(VCL::Module::OS);
# Specify the version of this module
our $VERSION = '2.00';
# Specify the version of Perl to use
use 5.008000;
use strict;
use warnings;
use diagnostics;
use VCL::utils;
##############################################################################
=head1 OBJECT METHODS
=cut
#/////////////////////////////////////////////////////////////////////////////
=head2 capture_prepare
Parameters :
Returns :
Description :
=cut
sub capture_prepare {
my $self = shift;
if (ref($self) !~ /linux/i) {
notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
return 0;
}
my $request_id = $self->data->get_request_id();
my $reservation_id = $self->data->get_reservation_id();
my $image_id = $self->data->get_image_id();
my $image_os_name = $self->data->get_image_os_name();
my $management_node_keys = $self->data->get_management_node_keys();
my $image_os_type = $self->data->get_image_os_type();
my $image_name = $self->data->get_image_name();
my $imagemeta_sysprep = $self->data->get_imagemeta_sysprep();
my $computer_id = $self->data->get_computer_id();
my $computer_short_name = $self->data->get_computer_short_name();
my $computer_node_name = $self->data->get_computer_node_name();
my $computer_type = $self->data->get_computer_type();
my $user_id = $self->data->get_user_id();
my $user_unityid = $self->data->get_user_login_id();
my $managementnode_shortname = $self->data->get_management_node_short_name();
my $computer_private_ip = $self->data->get_computer_private_ip();
notify($ERRORS{'OK'}, 0, "beginning Linux-specific image capture preparation tasks: $image_name on $computer_short_name");
my @sshcmd;
# Remove user and clean external ssh file
if ($self->delete_user()) {
notify($ERRORS{'OK'}, 0, "$user_unityid deleted from $computer_node_name");
}
if ($IPCONFIGURATION eq "static") {
#so we don't have conflicts we should set the public adapter back to dhcp
# reset ifcfg-eth1 back to dhcp
# when boot strap it will be set to dhcp
my @ifcfg;
my $tmpfile = "/tmp/createifcfg$computer_node_name";
push(@ifcfg, "DEVICE=eth1\n");
push(@ifcfg, "BOOTPROTO=dhcp\n");
push(@ifcfg, "STARTMODE=onboot\n");
push(@ifcfg, "ONBOOT=yes\n");
#write to tmpfile
if (open(TMP, ">$tmpfile")) {
print TMP @ifcfg;
close(TMP);
}
else {
#print "could not write $tmpfile $!\n";
notify($ERRORS{'OK'}, 0, "could not write $tmpfile $!");
}
#copy to node
if (run_scp_command($tmpfile, "$computer_node_name:/etc/sysconfig/network-scripts/ifcfg-$ETHDEVICE", $management_node_keys)) {
}
if (unlink($tmpfile)) {
}
} ## end if ($IPCONFIGURATION eq "static")
notify($ERRORS{'OK'}, 0, "returning 1");
return 1;
} ## end sub capture_prepare
#/////////////////////////////////////////////////////////////////////////////
=head2 capture_start
Parameters :
Returns :
Description :
=cut
sub capture_start {
my $self = shift;
if (ref($self) !~ /linux/i) {
notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
return 0;
}
my $management_node_keys = $self->data->get_management_node_keys();
my $image_name = $self->data->get_image_name();
my $computer_short_name = $self->data->get_computer_short_name();
my $computer_node_name = $self->data->get_computer_node_name();
notify($ERRORS{'OK'}, 0, "initiating Linux image capture: $image_name on $computer_short_name");
notify($ERRORS{'OK'}, 0, "initating reboot for Linux imaging sequence");
run_ssh_command($computer_node_name, $management_node_keys, "/sbin/shutdown -r now", "root");
notify($ERRORS{'OK'}, 0, "sleeping for 90 seconds while machine shuts down and reboots");
sleep 90;
notify($ERRORS{'OK'}, 0, "returning 1");
return 1;
} ## end sub capture_start
#/////////////////////////////////////////////////////////////////////////////
=head2 delete_user
Parameters :
Returns :
Description :
=cut
sub delete_user {
my $self = shift;
if (ref($self) !~ /linux/i) {
notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
return 0;
}
# Make sure the user login ID was passed
my $user_login_id = shift;
$user_login_id = $self->data->get_user_login_id() if (!$user_login_id);
if (!$user_login_id) {
notify($ERRORS{'WARNING'}, 0, "user could not be determined");
return 0;
}
# Make sure the user login ID was passed
my $computer_node_name = shift;
$computer_node_name = $self->data->get_computer_node_name() if (!$computer_node_name);
if (!$computer_node_name) {
notify($ERRORS{'WARNING'}, 0, "computer node name could not be determined");
return 0;
}
# Use userdel to delete the user
# Do not use userdel -r, it will affect HPC user storage for HPC installs
my $user_delete_command = "/usr/sbin/userdel $user_login_id";
my @user_delete_results = run_ssh_command($computer_node_name, $IDENTITY_bladerhel, $user_delete_command, "root");
foreach my $user_delete_line (@{$user_delete_results[1]}) {
if ($user_delete_line =~ /currently logged in/) {
notify($ERRORS{'WARNING'}, 0, "user not deleted, $user_login_id currently logged in");
return 0;
}
}
# User successfully deleted
# Remove user from sshd config
my $external_sshd_config_path = "$computer_node_name:/etc/ssh/external_sshd_config";
my $external_sshd_config_temp_path = "/tmp/$computer_node_name.sshd";
# Retrieve the node's external_sshd_config file
if (run_scp_command($external_sshd_config_path, $external_sshd_config_temp_path, $IDENTITY_bladerhel)) {
notify($ERRORS{'DEBUG'}, 0, "retrieved $external_sshd_config_path");
}
else {
notify($ERRORS{'WARNING'}, 0, "sshd config not cleaned up, failed to retrieve $external_sshd_config_path");
return 0;
}
# Remove user from sshd config file
# Get the contents of the sshd config file
if (open(SSHD_CFG_TEMP, $external_sshd_config_temp_path)) {
my @external_sshd_config_lines = <SSHD_CFG_TEMP>;
close SSHD_CFG_TEMP;
# Loop through the lines, clear out AllowUsers lines
foreach my $external_sshd_config_line (@external_sshd_config_lines) {
$external_sshd_config_line = "" if ($external_sshd_config_line =~ /AllowUsers/);
}
# Rewrite the temp sshd config file with the modified contents
if (open(SSHD_CFG_TEMP, ">$external_sshd_config_temp_path")) {
print SSHD_CFG_TEMP @external_sshd_config_lines;
close SSHD_CFG_TEMP;
}
# Copy the modified file back to the node
if (run_scp_command($external_sshd_config_temp_path, $external_sshd_config_path, $IDENTITY_bladerhel)) {
notify($ERRORS{'DEBUG'}, 0, "modified file copied back to node: $external_sshd_config_path");
# Delete the temp file
unlink $external_sshd_config_temp_path;
# Restart external sshd
if (run_ssh_command($computer_node_name, $IDENTITY_bladerhel, "/etc/init.d/ext_sshd restart")) {
notify($ERRORS{'DEBUG'}, 0, "restarted ext_sshd on $computer_node_name");
}
return 1;
} ## end if (run_scp_command($external_sshd_config_temp_path...
else {
notify($ERRORS{'WARNING'}, 0, "failed to copy modified file back to node: $external_sshd_config_path");
# Delete the temp file
unlink $external_sshd_config_temp_path;
return 0;
}
} ## end if (open(SSHD_CFG_TEMP, $external_sshd_config_temp_path...
else {
notify($ERRORS{'WARNING'}, 0, "failed to open temporary sshd config file: $external_sshd_config_temp_path");
return 0;
}
} ## end sub delete_user
#/////////////////////////////////////////////////////////////////////////////
1;
__END__
=head1 BUGS and LIMITATIONS
There are no known bugs in this module.
Please report problems to the VCL team (vcl_help@ncsu.edu).
=head1 AUTHOR
Aaron Peeler, aaron_peeler@ncsu.edu
Andy Kurth, andy_kurth@ncsu.edu
=head1 SEE ALSO
L<http://vcl.ncsu.edu>
=cut