summaryrefslogtreecommitdiffstats
path: root/os-plugins/plugins/vmware/OpenSLX/OSPlugin/vmware.pm
blob: 16dfe520887a8f302a847ee1b2e7649737e94198 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
# Copyright (c) 2008 - OpenSLX GmbH
#
# This program is free software distributed under the GPL version 2.
# See http://openslx.org/COPYING
#
# If you have any feedback please consult http://openslx.org/feedback and
# send your suggestions, praise, or complaints to feedback@openslx.org
#
# General information about OpenSLX can be found at http://openslx.org/
# -----------------------------------------------------------------------------
# vmware.pm
#    - declares necessary information for the vmware plugin
# -----------------------------------------------------------------------------
package OpenSLX::OSPlugin::vmware;

use strict;
use warnings;

use base qw(OpenSLX::OSPlugin::Base);

use File::Basename;
use File::Path;

use OpenSLX::Basics;
use OpenSLX::Utils;

sub new
{
    my $class = shift;

    my $self = {
        name => 'vmware',
    };

    return bless $self, $class;
}

sub getInfo
{
    my $self = shift;

    return {
        description => unshiftHereDoc(<<'        End-of-Here'),
            !!! descriptive text missing here !!!
        End-of-Here
        precedence => 70,
    };
}

sub getAttrInfo
{
    # returns a hash-ref with information about all attributes supported
    # by this specific plugin
    my $self = shift;

    # This default configuration will be added as attributes to the default
    # system, such that it can be overruled for any specific system by means
    # of slxconfig.
    return {
        # attribute 'active' is mandatory for all plugins
        'vmware::active' => {
            applies_to_systems => 1,
            applies_to_clients => 0,
            description => unshiftHereDoc(<<'            End-of-Here'),
                should the 'vmware'-plugin be executed during boot?
            End-of-Here
            content_regex => qr{^(0|1)$},
            content_descr => '1 means active - 0 means inactive',
            default => '1',
        },
        # attribute 'imagesrc' defines where we can find vmware images
        'vmware::imagesrc' => {
            applies_to_systems => 1,
            applies_to_clients => 1,
            description => unshiftHereDoc(<<'            End-of-Here'),
                Where do we store our vmware images? NFS? Filesystem?
            End-of-Here
            #TODO: check if the input is valid
            #content_regex => qr{^(0|1)$},
            content_descr => 'Allowed values: path or URI',
            default => '',
        },
        # attribute 'bridge' defines if bridged network mode should be
        # switched on
        'vmware::bridge' => {
            applies_to_systems => 1,
            applies_to_clients => 1,
            description => unshiftHereDoc(<<'            End-of-Here'),
                Should the bridging (direct access of the vmware clients
                to the ethernet the host is connected to) be enabled
            End-of-Here
            content_regex => qr{^(0|1)$},
            content_descr => 'Allowed values: 0 or 1',
            default => '1',
        },
        # attribute 'vmnet1' defines if the host connection network mode 
        # should be switched on and NAT should be enabled
        'vmware::vmnet1' => {
            applies_to_systems => 1,
            applies_to_clients => 1,
            description => unshiftHereDoc(<<'            End-of-Here'),
                Format ServerIP/Netprefix without NAT
                Format ServerIP/Netprefix,NAT enables NAT/Masquerading
            End-of-Here
            #TODO: check if the input is valid
            #content_regex => qr{^(0|1)$},
            content_descr => 'Allowed value: IP/Prefix[,NAT]',
            default => '192.168.101.1/24,NAT',
        },
        # attribute 'vmnet8' defines if vmware specific NATed network mode
        # should be switched on
        'vmware::vmnet8' => {
            applies_to_systems => 1,
            applies_to_clients => 1,
            description => unshiftHereDoc(<<'            End-of-Here'),
                Format ServerIP/Netprefix
            End-of-Here
            #TODO: check if the input is valid
            #content_regex => qr{^(0|1)$},
            content_descr => 'Allowed value: IP/Prefix',
            default => '192.168.102.1/24',
        },
        # attribute 'kind' defines which set of VMware binaries should be 
        # activated ('local' provided with the main installation set).
        'vmware::kind' => {
            applies_to_vendor_os => 0,
            applies_to_systems => 1,
            applies_to_clients => 1,
            description => unshiftHereDoc(<<'            End-of-Here'),
                Which set of VMware binaries to use: installed (local) or provided by an
                other plugin (e.g. Workstation 5.5: vmws5.5, Player 2.0: vmpl2.0, ...)
            End-of-Here
            # only allow the supported once...
            # TODO: modify if we know which of them work
            #content_regex => qr{^(local|vmws(5\.5|6.0)|vmpl(1\.0|2\.0))$},
            content_regex => qr{^(local|vmpl2\.0)$},
            content_descr => 'Allowed values: local, vmpl2.0',
            default => 'local',
        },
        ##
        ## only stage1 setup options: different kinds to setup
        'vmware::local' => {
            applies_to_vendor_os => 1,
            applies_to_system => 0,
            applies_to_clients => 0,
            description => unshiftHereDoc(<<'            End-of-Here'),
                Set's up stage1 configuration for a local installed
                vmplayer or vmware workstation
            End-of-Here
            content_regex => qr{^(1|0)$},
            content_descr => '1 means active - 0 means inactive',
            default => '1',
        },
        'vmware::vmpl2.0' => {
            applies_to_vendor_os => 1,
            applies_to_system => 0,
            applies_to_clients => 0,
            description => unshiftHereDoc(<<'            End-of-Here'),
                Install and configure vmplayer v2
            End-of-Here
            content_regex => qr{^(1|0)$},
            content_descr => '1 means active - 0 means inactive',
            default => '0',
        },
        # ** set of attributes for the installation of VM Workstation/Player
        # versions. More than one package could be installed in parallel.
        # To be matched to/triggerd by 'vmware::kind'
    };
}


sub installationPhase
{
    my $self                      = shift;

    $self->{pluginRepositoryPath} = shift;
    $self->{pluginTempPath}       = shift;
    $self->{openslxPath}          = shift;
    $self->{attrs}                = shift;
    

    # kinds we will configure and install
    # TODO: write a list of installed/setted up and check it in stage3
    #       this will avoid conflict of configured vmware version in
    #       stage3 which are not setted up or installed in stage1
    if ($self->{attrs}->{'vmware::local'} == 1) {
        $self->_localInstallation();
    }
    if ($self->{attrs}->{'vmware::vmpl2.0'} == 1) {
        $self->_vmpl2Installation();
    }

}

sub removalPhase
{
    my $self                 = shift;
    my $pluginRepositoryPath = shift;
    my $pluginTempPath       = shift;
    
    rmtree ( [ $pluginRepositoryPath ] );
    # restore old start scripts - to be discussed
    my @files = qw( vmware vmplayer );
    foreach my $file (@files) {
        if (-e $file) {
            unlink("/usr/bin/$file");
            rename("/usr/bin/$file.slx-bak", "/usr/bin/$file");
        }
    }
    return;
}


#######################################
## local, non-general OpenSLX functions
#######################################

# write the runlevelscript depending on the version
sub _writeRunlevelScript
{
    my $self     = shift;
    my $location = shift;
    my $file     = shift;
    
    # $location points to the path where vmware helpers are installed
    # call the distrospecific fillup
    my $runlevelScript = $self->{distro}->fillRunlevelScript($location);

    # OLTA: this backup strategy is useless if invoked twice, so I have
    #       deactivated it
    # rename($file, "${file}.slx-bak") if -e $file;

    spitFile($file, $runlevelScript);
}


# writes the wrapper script for vmware workstation and player, depending
# on the flag. If player: just player wrapper, if ws: ws+player wrapper
# usage: _writeWrapperScript("$vmpath", "$kind", "player")
#        _writeWrapperScript("$vmpath", "$kind", "ws")
sub _writeWrapperScript
{
    my $self   = shift;
    my $vmpath = shift;
    my $kind   = shift;
    my $type   = shift;
    my @files;

    if ("$type" eq "ws") {
        @files = qw(vmware vmplayer);
    } else {
        @files = qw(vmplayer);
    }

    foreach my $file (@files) {
        # create our own simplified version of the vmware and player wrapper
        # Depending on the configured kind it will be copied in stage3
        # because of tempfs of /var but not /usr we link the file
        # to /var/..., where we can write in stage3
        my $script = unshiftHereDoc(<<"        End-of-Here");
            #!/bin/sh
            # written by OpenSLX-plugin 'vmware' in Stage1
            # radically simplified version of the original script $file by VMware Inc.
        End-of-Here

        # kinda ugly and we only need it for local. Preserves errors
        if ($kind ne "local") {
            $script .= unshiftHereDoc(<<"            End-of-Here");
                export LD_LIBRARY_PATH=$vmpath/lib
                export GTK_PIXBUF_MODULE_FILE=$vmpath/libconf/etc/gtk-2.0/gdk-pixbuf.loaders
                export GTK_IM_MODULE_FILE=$vmpath/libconf/etc/gtk-2.0/gtk.immodules
                export FONTCONFIG_PATH=$vmpath/libconf/etc/fonts
                export PANGO_RC_FILE=$vmpath/libconf/etc/pango/pangorc
                # possible needed... but what are they good for?
                #export GTK_DATA_PREFIX=
                #export GTK_EXE_PREFIX=
                #export GTK_PATH=
            End-of-Here
        }

        $script .= unshiftHereDoc(<<"        End-of-Here");
            PREFIX=$vmpath # depends on the vmware location
            exec "\$PREFIX"'/lib/wrapper-gtk24.sh' \\
                "\$PREFIX"'/lib' \\
                "\$PREFIX"'/bin/$file' \\
                "\$PREFIX"'/libconf' "\$@"
        End-of-Here

        # TODO: check if these will be overwritten if we have more as
        # local defined (add the version/type like vmpl1.0, vmws5.5, ...)
        # then we have a lot of files easily distinguishable by there suffix
        spitFile("$self->{'pluginRepositoryPath'}/$kind/$file", $script);
        chmod 0755, "$self->{'pluginRepositoryPath'}/$kind/$file";
    }
}


########################################################################
## Functions, which setup the different environments (local, ws-v(5.5|6),
##                                                    player-v(1|2)
## Seperation makes this file more readable. Has a bigger benefit as
## one big copy function. Makes integration of new versions easier.
########################################################################

# local installation
sub _localInstallation
{
    my $self     = shift;

    my $kind   = "local";
    my $vmpath = "/usr/lib/vmware";
    my $vmbin  = "/usr/bin";
    my $vmversion = "";
    my $vmbuildversion = "";

    my $pluginFilesPath 
        = "$self->{'openslxPath'}/lib/plugins/$self->{'name'}/files";
    my $installationPath = "$self->{'pluginRepositoryPath'}/$kind";

    mkpath($installationPath);

    # if vmware ws is installed, vmplayer is installed, too.
    # we will only use vmplayer
    if (-e "/usr/lib/vmware/bin/vmplayer") {

        ##
        ## Get and write version informations

        # get version information about installed vmplayer
        open(FH, "/usr/lib/vmware/bin/vmplayer");
        $/ = undef;
        my $data = <FH>;
        close FH;
        # perhaps we need to recheck the following check. depending
        # on the installation it could differ and has multiple build-
        # strings
        if ($data =~ m{[^\d\.](\d\.\d) build-(\d+)}) {
            $vmversion = $1;
            $vmbuildversion = $2;
        }
        # else { TODO: errorhandling if file or string doesn't exist }
        chomp($vmversion);
        chomp($vmbuildversion);

        # write informations about local installed vmplayer in file
        # TODO: perhaps we don't need this file.
        # TODO2: write vmbuildversion and stuff in runvmware in stage1
        open FILE, ">$self->{'pluginRepositoryPath'}/$kind/versioninfo.txt"
            or die $!;
        print FILE "vmversion=\"$vmversion\"\n";
        print FILE "vmbuildversion=\"$vmbuildversion\"\n";
        close FILE;

        ##
        ## Copy needed files

        # copy 'normal' needed files
        my @files = qw( nvram.5.0);
        foreach my $file (@files) {
            copyFile("$pluginFilesPath/$file", "$installationPath");
        }
        # copy depends on version and rename it to runvmware, safes one check in stage3
        if ($vmversion < "6") {
            print "\n\nDEBUG: player version $vmversion, we use -v1\n\n";
            copyFile("$pluginFilesPath/runvmware-player-v1", "$installationPath", "runvmware");
        } else {
            print "\n\nDEBUG: player version $vmversion, we use -v2\n\n";
            copyFile("$pluginFilesPath/runvmware-player-v2", "$installationPath", "runvmware");
        }

        ##
        ## Create runlevel script
        my $runlevelScript = "$self->{'pluginRepositoryPath'}/$kind/vmware.init";
        $self->_writeRunlevelScript($vmbin, $runlevelScript);

        ##
        ## Create wrapperscripts
        if (-e "/usr/bin/vmware") {
            $self->_writeWrapperScript("$vmpath", "$kind", "ws")
        } else {
            $self->_writeWrapperScript("$vmpath", "$kind", "player")
        }
        
        ##
        ## replacement with our, faster wrapper script
        
        # rename the default vmplayer script and copy it. remove function takes
        # care about plugin remove. We only need this part if vmplayer
        # or ws is installed on the local system
        rename("/usr/bin/vmplayer", "/usr/bin/vmplayer.slx-bak");
        copyFile("$self->{'pluginRepositoryPath'}/$kind/vmplayer", "/usr/bin");
        # the same with vmware, if ws is installed
        if (-e "/usr/bin/vmware") {
            rename("/usr/bin/vmware", "/usr/bin/vmware.slx-bak");
            copyFile("$self->{'pluginRepositoryPath'}/$kind/vmware", "/usr/bin");
         }
            
    }
    # else { TODO: errorhandling }
}


sub _vmpl2Installation {
    my $self     = shift;

    my $kind   = "vmpl2.0";
    my $vmpath = "/opt/openslx/plugin-repo/vmware/$kind/root/lib/vmware";
    my $vmbin  = "/opt/openslx/plugin-repo/vmware/$kind/root/bin";
    my $vmversion = "TODO_we_need_it_for_enhanced_runvmware_config_in_stage?";
    my $vmbuildversion = "TODO_we_need_it_for_enhanced_runvmware_config_in_stage1";

    my $pluginFilesPath 
        = "$self->{'openslxPath'}/lib/plugins/$self->{'name'}/files";
    my $installationPath = "$self->{'pluginRepositoryPath'}/$kind";

    mkpath($installationPath);

    ##
    ## Copy needed files

    # copy 'normal' needed files
    my @files = qw( nvram.5.0 install-vmpl2.0.sh );
    foreach my $file (@files) {
        copyFile("$pluginFilesPath/$file", "$installationPath");
    }
    # copy on depending runvmware file
    copyFile("$pluginFilesPath/runvmware-player-v2", "$installationPath", "runvmware");

    ##
    ## Download and install the binarys
    system("/bin/sh /opt/openslx/plugin-repo/$self->{'name'}/$kind/install-$kind.sh");

    ##
    ## Create runlevel script
    my $runlevelScript = "$self->{'pluginRepositoryPath'}/$kind/vmware.init";
    $self->_writeRunlevelScript($vmbin, $runlevelScript);

    ##
    ## Create wrapperscripts
    $self->_writeWrapperScript("$vmpath", "$kind", "player")
        
}


1;