Author: bmbouter
Date: Mon Mar 30 18:55:20 2009
New Revision: 760101

URL: http://svn.apache.org/viewvc?rev=760101&view=rev
Log:
VCL-123

This commit adds basic Ubuntu support through an Ubuntu.pm OS module using the 
new OS module framework corresponding to the VCL-123 ticket.  The Linux.pm 
isn't adequate to handle the user adding because Ubuntu doesn't support setting 
the password using --stdin which is what the core defaults to if there is not 
OS module to tell it how to do it otherwise.  Additionally, the core isn't 
suitable to handle the user adding because it contains the '-g ncsu' field 
which is not appropriate for places outside of NCSU.


Added:
    incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Ubuntu.pm

Added: incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Ubuntu.pm
URL: 
http://svn.apache.org/viewvc/incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Ubuntu.pm?rev=760101&view=auto
==============================================================================
--- incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Ubuntu.pm (added)
+++ incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Ubuntu.pm Mon Mar 30 
18:55:20 2009
@@ -0,0 +1,362 @@
+#!/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: Ubuntu.pm 1945 2008-12-11 20:58:08Z fapeeler $
+##############################################################################
+
+=head1 NAME
+
+VCL::Module::OS::Ubuntu.pm - VCL module to support Ubuntu operating systems
+
+=head1 SYNOPSIS
+
+ Needs to be written
+
+=head1 DESCRIPTION
+
+ This module provides VCL support for Ubuntu operating systems.
+
+=cut
+
+##############################################################################
+package VCL::Module::OS::Ubuntu;
+
+# 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) !~ /ubuntu/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 Ubuntu-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) !~ /ubuntu/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 Ubuntu image capture: $image_name 
on $computer_short_name");
+
+       notify($ERRORS{'OK'}, 0, "initating reboot for Ubuntu 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) !~ /ubuntu/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
+       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
+
+#/////////////////////////////////////////////////////////////////////////////
+
+sub reserve {
+       my $self = shift;
+       if (ref($self) !~ /ubuntu/i) {
+               notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a 
function, it must be called as a class method");
+               return 0;
+       }
+
+       notify($ERRORS{'DEBUG'}, 0, "Enterered reserve() in the Ubuntu OS 
module");
+       my $user_name = $self->data->get_user_login_id();
+       my $computer_node_name = $self->data->get_computer_node_name();
+       my $image_identity = $self->data->get_image_identity;
+       my $reservation_password = $self->data->get_reservation_password();
+
+       my $useradd_string = "/usr/sbin/useradd -d /home/$user_name -m -g users 
$user_name";
+
+       my @sshcmd = run_ssh_command($computer_node_name, $image_identity, 
$useradd_string, "root");
+       foreach my $l (@{$sshcmd[1]}) {
+               if ($l =~ /user $user_name exists/) {
+                       notify($ERRORS{'OK'}, 0, "detected user already has 
account");
+               }
+
+       }
+
+       my $encrypted_pass;
+       undef @sshcmd;
+       @sshcmd = run_ssh_command($computer_node_name, $image_identity, 
"/usr/bin/mkpasswd $reservation_password", "root");
+       foreach my $l (@{$sshcmd[1]}) {
+               $encrypted_pass = $l;
+               notify($ERRORS{'DEBUG'}, 0, "Found the encrypted password as 
$encrypted_pass");
+       }
+
+       undef @sshcmd;
+       @sshcmd = run_ssh_command($computer_node_name, $image_identity, 
"usermod -p $encrypted_pass $user_name", "root");
+       foreach my $l (@{$sshcmd[1]}) {
+               notify($ERRORS{'DEBUG'}, 0, "Updated the user password .... L 
is $l");
+       }
+
+       return 1;
+} ## end sub delete_user
+
+sub grant_access {
+       my $self = shift;
+       if (ref($self) !~ /ubuntu/i) {
+               notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a 
function, it must be called as a class method");
+               return 0;
+       }
+
+       notify($ERRORS{'DEBUG'}, 0, 
"===+++++++++++========+++++++++++++Enterered grant_access in Ubuntu");
+       
+       my $user_name = $self->data->get_user_login_id();
+       my $computer_node_name = $self->data->get_computer_node_name();
+       my $reservation_password = $self->data->get_reservation_password();
+       my $image_identity = $self->data->get_image_identity;
+
+       notify($ERRORS{'OK'}, 0, "user_name $user_name");
+       notify($ERRORS{'OK'}, 0, "comp_node_name $computer_node_name");
+       notify($ERRORS{'OK'}, 0, "identity key $image_identity");
+
+#              my @sshcmd = run_ssh_command($computer_node_name, 
$image_identity, "echo $reservation_password \| /usr/bin/passwd -f $user_name 
--stdin", "root");
+#              foreach my $l (@{$sshcmd[1]}) {
+#                      if ($l =~ /authentication tokens updated successfully/) 
{
+#                              notify($ERRORS{'OK'}, 0, "successfully changed 
local password account $user_name");
+#                              return 1;
+#                      }
+#              }
+       
+       return 1;
+} ## 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_h...@ncsu.edu).
+
+=head1 AUTHOR
+
+ Aaron Peeler, aaron_pee...@ncsu.edu
+ Andy Kurth, andy_ku...@ncsu.edu
+
+=head1 SEE ALSO
+
+L<http://vcl.ncsu.edu>
+
+
+=cut


Reply via email to