Copyright (C) 1999-2005
Mike McCauley and Hugh Irvine
Developers guide to customizing and extending the Nets network inventory and management system.
For Nets Revision 2.5
Nets is a graphical source code product providing a flexible and extensible environment for maintaining essential network inventory, configuration and cost information in a platform and database independent manner.
Nets provides a physical model of the network, from which it is simple and straightforward to derive and display any number of textual, logical or graphical views.
Nets is designed by network engineering professionals to address the common problems encountered in network design, management and operation.
In keeping with its flexible and extensible design, Nets provides a number of ways to customize and extend its functionality. You can add and alter functions specifically for your own site, and you can also create reusable packages of functions and features that can be distributed and installed at other Nets sites.
This document describes the different methods that can be used to customize and extend Nets.
Readers of this document are expected to have some knowledge of system administration, and to have an understanding of standard Nets functionality, SQL databases and the Perl programming language.
Nets has been designed to be easily extended, enhanced, customized and modified, both to suit your own special needs, and also to distribute changes to other Nets users. There is a community of Nets users who contribute packages of code and functions, and all Nets users are encouraged to contribute interesting and useful enhancements.
There are a range of ways that Nets can be modified, and you may use one or more methods depending on the type of changes or enhancements you need to make:
The standard Nets distribution includes a number of files and directories, and this section describes the major directories included and how they are used.
When a Nets distribution file is unpacked (using tar/gzip or WinZip, depending on your platform), it creates a single directory containing the entire Nets software tree. The top of this distribution tree will be named something like Nets-2.1 , depending on exactly which version of Nets you have. This top level directory contains the Nets executable programs, some data files, and a number of important sub-directories described below.
The executable programs include netsmain.pl (the main Nets user program), plus some utility programs, netscreate.pl, netsload.pl, netsdump.pl and netspkginstall.pl. When Nets is installed, these executable programs are copied to the standard Perl binary directory (typically /usr/local/bin on Unix, or C:\Perl\bin on Windows).
In the following sections, <NetsDir> means the directory at the top of your Nets distribution.
This directory includes all the Nets Perl modules required by the Nets programs mentioned above. Each module has a .pm extension. When Nets is installed, these modules are copied to the standard Perl site library directory (typically /usr/local/lib/perl5/site_perl on Unix, or C:\Perl\site on Windows). You can add your own modules to Nets by adding them to this directory and reinstalling Nets.
Contains the standard Nets icons, which are using on Nets Drawings and other parts of the Nets user interface.
Nets has been designed and implemented using modern Object Oriented software technology. This design allows Nets developers to easily use and extend the core features of Nets. Figure 1 shows the core Nets object hierarchy.
The core Nets product includes the Perl classes shown below. In general, each Nets Perl class is defined by a Perl package (not to be confused with a Nets package), using conventional Perl object packages. You can add your own classes using Plug-ins, or by modifying the Nets code.
Provides a range of low level SQL database access routines for doing queries, inserts, updates and deletes. $main::db refers to the (usually) one instance of the DBSQL class.
Provides a range of routines for managing the contents of the SQL tables as described by Schema.pm. Uses the services of DBSQL to interact with the SQL database.
This class provides "persistent objects", used to implement Nets Objects such as DEVICE, LINK, NETSUSER etc. Uses the services of DBUtil to save objects to and from the SQL database.
Subclass of Object used for storing information about Nets Users, including Preferences and Permissions.
Provides a generalized Tk window class, with a number of common routines and data structures used by most Nets windows, including:
Subclass of GenericDialog adds features required by a range of object editors, such as OK, Cancel and Help buttons, object saving, and list of available objects.
Subclass of GenericEdit provides object editing services for most low-level Nets objects. Objects are displayed according to the user interface description for the Object class as described in UIDesc.pm. User permissions are observed.
Subclass of GenericEdit that provides preview and selection of icons from the <NetsDir>/images/icons directory.
Subclass of GenericEdit that provides preview and selection of fonts. Font names are represented with a platform independent font naming scheme.
Subclass of ObjectEdit that provides a specialized user interface for editing Nets User objects.
Subclass of GenericDialog that provides listing and searching for Nets objects. The displayed fields, and searchable fields are described in UIDesc.pm.
Subclass of GenericDialog that provides selection and loading of Templates, as well as click-through to the objects created by the Template.
Subclass of GenericDialog that provides a window for visualizing IPV4 address usage.
Subclass of GenericDialog that provides a window for viewing Nets log messages in real time. (This class provides a working example of registering and deregistering Hooks).
Nets is a source code product, and is provided with all (or most, depending on your license) of the source code. One easy way to modify the operation of Nets is to modify the source code directly. While this is easy, it is discouraged, since whenever a new version of Nets is released, you will need to migrate your changes from the old version to the new version. In fact the preferred way to add or change Nets functions is to use a Plug-in (see Section 7.0 ).
However, if you really do wish to alter the source code, the following sections will provide some information about where and how you should make your changes. The preferred way of changing the source code is to edit the source file in the Nets distribution, and then reinstall Nets, so that the changes are moved to the public Perl binary and module directories.
Migrating your source code changes from Nets version to version can be made easier with the unix tools diff(1) and patch(1).
This file contains the definitions of all the SQL tables used by Nets. The tables are described in a data structure, and in a database independent way. Changing Schema.pm allows you to easily add, change and remove tables and columns from your Nets database.
You might, for example wish to add new columns to a table in order to store some site-specific information that your organization needs. Note that you would normally also need to add something to the ObjectEdit user interface for that object, by modifying UIDesc.pm (see Section 5.2 ).
The database schema described in Schema.pm is used by Nets to load and save Nets Objects. It is also used by netscreate.pl when it creates (or recreates) a database table. You should note that altering Schema.pm will not, on its own, change the table in the database, it merely changes what tables and columns Nets will refer to. You might need to drop and recreate a table, or perhaps add or drop columns by hand, if dropping a table is not possible. The Nets utilities can provide some help with this. For example, you could dump your entire database with netsdump.pl, alter the schema, recreate the tables with netscreate.pl -dropfirst, then reload the data with netsload.pl.
If you are just adding a new table, it should be sufficient to just do netscreate.pl. By default, netscreate.pl does not drop any existing tables, so the new table will be created without affecting any existing table (Note, you will get a number of warning messages as netscreate.pl tries to create all the already existing tables).
Schema.pm defines the data structure %Nets::schema. This is a perl hash, containing an entry for each table used by Nets. Each entry defines the columns, keys and name for that table. Here is a typical example, which defines a table for network addresses.
%Nets::schema =
(
ADDRESS => {
'title' => 'Address',
'description' => 'One record for each address',
'columns' => {
ADDRESSTYPE => [ 'fk', 'ADDRESSTYPE.ID' ],
DESCRIPTION => [ 'varchar', 200],
DNSNAME => [ 'varchar', 50 ],
ID => [ 'id' ],
NAME => [ 'varchar', 50 ],
NETMASK => [ 'varchar', 50 ],
OVERSION => [ 'version' ],
},
'primary_key' => [ 'ID' ],
},
As can be seen, the hash entry for ADDRESS is in fact an anonymous hash with entries for title, description, columns and primary_key. The following types are supported:
|
Anonymoush hash, each entry and array of column definition entries, see Table 2
e.g.: 'columns' => { |
|
|
Optional array of column names. The primary key will be formed from all the columns named. |
|
|
Optional array of arrays of column names. A unique index will be created for each set of column names.
e.g.: `unique' => [ [ `NAME', `NETMASK'], will create two unique indexes, one on NAME and NETMASK, and the other unique index on DNSNAME and DESCRIPTION. |
|
|
Optional array of arrays of column names. A (non-unique) index will be created for each set of column names.
e.g.: `unique' => [ [ `NAME', `NETMASK'], will create two indexes, one on NAME and NETMASK, and the other on DNSNAME and DESCRIPTION. |
This file defines the user interface for each type of Nets object. It is used by the ObjectEdit and ObjectList classes to construct the right type of user interface for each type of Nets object. In general terms, for each type of object, it specifies which database columns are to be displayed to the user, and how to display them. Many features of the user interface can be customized and controlled by changing the entries in UIDesc.pm
UIDesc.pm defines 2 hashes: %Nets::UIDesc::editors , and %Nets::UIDesc::listers . Editors defines the user interface for editing objects, used by ObjectEdit.pm. Listers defines the user interface for listing objects, used by ObjectList.pm. If there is no entry for a given object type, then no editing window or search/list window (as the case may be) can be created.
This hash defines the user interface for editing objects. It is used by ObjectEdit.pm to construct the user interface appropriate to each type of Nets object.
Each entry in editors is an anonymous hash, with each entry in that hash describing some element of the user interface. Not all elements are required, some being optional. Here is a typical example, which defines the object editing user interface for ADDRESS objects:
%editors =
(
ADDRESS => {
title => 'Address',
index_field => ['text', 'NAME'],
main_window =>
[
['entry', 'NAME', 'Address', 'This address', undef, 50],
['entry', 'DNSNAME', 'DNS Name', 'The DNS name', undef, 50],
['entry', 'NETMASK', 'Netmask', 'The netmask', undef, 50],
['fkmenu', 'ADDRESSTYPE', 'Address Family', 'Address family'],
['entry', 'DESCRIPTION', 'Description', 'Description', undef,
50],
],
defaults => {
ADDRESSTYPE => 2, # IP V4
NETMASK => '255.255.255.0',
},
validator => \&validateAddressEditor,
tools =>
[
['Edit INTERFACEs with this ADDRESS',
'Nets::Session::show',
type => 'INTERFACE',
where => 'ADDRESS=%{context_id}',
title => 'Interfaces with Address'],
['Show Address Map',
'Nets::Session::show',
class => 'Nets::AddressMap'],
],
view_permissions => ('VIEW_NETWORK'),
edit_permissions => ('EDIT_NETWORK'),
sortby => 'IP address',
},
|
Specifies which column(s) from each object are to be shown in the object list on the left side of the editor window. Also specifies the display format for each column. |
|
|
A hash that specifies which column(s) from the currently selected object will be displayed in the main panel on the right hand side of the editing window. See Table 4 for details of the format of the entries in this hash. |
|
|
Optional hash that specifies a number of sub-panels to display as notebook tabs under the main panel on the right hand side of the editor. Within a panel, the same format as main_window is supported, See Table 4 for details of the format of the entries in this hash. |
|
|
Optional hash giving default values for each column. These defaults will be applied when a new object is created in the Editor. |
|
|
Optional reference to a function that will be called to validate the contents of the editor before the object is saved to the database. If the object validates OK, returns undef, else returns a string that will be displayed to the user. |
|
|
Optional array of tool definitions. Each definition results in an entry in the Tools menu for this object. See Table 6 . |
|
|
Optional array of permission names. In order to view the contents of an object of this type, the current Nets user must have one of the permissions mentioned here, or else VIEW_ANYTHING or VIEW_<objectname> permissions. |
|
|
Optional array of permission names. In order to change or delete the contents of an object of this type, the current Nets user must have one of the permissions mentioned here, or else EDIT_ANYTHING or EDIT_<objectname> permissions. |
|
|
Optional string, specifies the initial sort order to use in the object list on the left side of the editor. May be one of: |
|
The type of user interface widget to use to display this column. May be one of entry, datetime, ipv4address, text, static, timestamp, latlong, int, float, currency, menu, colour, font, icon, fkselect, fkmenu. See Table 5 for details. |
|
|
Short help text that appears in a help balloon over this field. |
|
|
For `menu', a reference to a function that returns a list of menu entries, use to populate the menu. For fkmenu and fkselect, a list of additional columns to show in the menu. |
|
|
entry, datetime and ipv4address, text, int, float, currency, the width of the text entry widget in characters. |
|
You should note that it is possible to alter the % Nets::UIDesc::editors hash without editing UIDesc.pm. For example, from within a Plug-in, you could add a new user interface description for a new type of object with something like this:
$Nets::UIDesc::editors{`MYNEWOBJECT'} =
{
title => 'My New Object',
index_field => ['text', 'NAME'],
main_window =>
.......
This hash defines the user interface for editing objects. It is used by ObjectList.pm to construct the user interface appropriate to each type of Nets object.
Each entry in listers is an anonymous hash, with each entry in that hash describing some element of the user interface. Not all elements are required, some being optional. Here is a typical example, which defines the object search/list user interface for ADDRESS objects:
%listers =
(
ADDRESS => {
title => 'Address',
main_window =>
[
['text', 'NAME', 'Address', 'Address', 20],
['text', 'DNSNAME', 'DNS Name', 'DNS name', 20],
['text', 'DESCRIPTION', 'Description', 'Brief description
of the usage of this address', 20],
['text', 'NETMASK', 'Netmask', 'The network netmask', 20],
['fkmenu', 'ADDRESSTYPE', 'Address Family', 'The type of
address family for this address', 10],
],
},
.......
|
A hash that specifies which column(s) from the currently selected object can be searched on, and which will be displayed in the list at the bottom of the window. See Table 8 for details of the format of the entries in this hash. |
|
The type of user interface widget to use to display this column. May be one of datetime, text, int, float, currency, fkmenu. See Table 9 for details. |
|
|
Short help text that appears in a help balloon over this field. |
|
|
For `menu', a reference to a function that returns a list of menu entries, use to populate the menu. For fkmenu and fkselect, a list of additional columns to show in the menu. |
|
|
entry, datetime and ipv4address, text, int, float, currency, the width of the text entry widget in characters. |
|
This file contains the initial values of various configuration variables that can be set within Nets. The Nets configuration in Site.pm can be overridden by a range of per-user and per-host sources, such as configuration files, command-line arguments, and User preferences in the database. Changing the configuration variables allows you to configure the default behaviour of Nets. Changing them in Site.pm makes those changes apply to all users who run Nets on the hosts where your Site.pm is installed, but still allows them to be overridden on a per-user or per-site basis.
Site.pm is amongst the last of the Nets support modules loaded when Nets starts up. It can therefore be used to override most functions and data within Nets.
You can also add site-specific code to Site.pm, and use that code to establish Hooks, change the user interface definitions or schema or change or override any code that is part of Nets. However, unless special conditions exist, we recommend that site-specific code be put in a Nets Plug-in (see Section 7.0 ).
Hooks are a Nets mechanism which allow your own Perl code to get control at specific times during normal Nets operation. For example, you can register a hook that will run your own code every time a Nets object is deleted from the database, perhaps to add or remove some site specific data from an external file.
Nets implements a number of hooks, each serving a specific purpose. Each hook has a name, and is run at a specific time during Nets processing. You can register any number of callbacks for the same hook; they will be run in the order in which they were registered.
Here is some typical code to create and register a hook:
sub logSomething
{
my ($p, $s, $self) = @_;
print "here I am in the registered logger: $p, $s\n";
}
......
&Nets::Hooks::register('log', [\&logSomething, $self]);
When the hook is subsequently run, the caller will pass a fixed number of arguments ($p and $s in the example above. The arguments depend on which hook is being called, but usually provide some information about what is being affected or operated on at the time the hook is run.
When the hook is registered, the registering function can also specify some private data to be passed to the hook each time it is called ($self in the example above).
Called just after an object is loaded from the database and a new Nets::Object instance created to hold the contents:
Called just after a new object is inserted into the database:
Plug-ins are the primary and preferred method for inserting new functionality into Nets. A Plug-in is a Perl program module that is loaded into Nets when the Nets main program (netsmain.pl) start up.
Plug-ins can contain any Perl code, and have first-class access to all Nets data structures and functions, exactly like the core Nets code.
Using Plug-ins, you can, for example:
Plug-ins (and other Nets files) can be distributed to other Nets users as part of a Nets Package (see Section 10.0 ). You are encouraged to publish your Nets Plug-ins, or send them to us, so we can include them in the Nets goodies or the Nets core distribution.
When netsmain.pl starts, it looks in the <PluginsPath> directory for files with the extension .npm (for Nets Plug-in Module). Any such files found will be loaded into Nets with the Perl `do' operator. Perl compilation or loading errors will be reported and logged. Therefore it is only necessary to put a Plug-in file into the <PluginsPath> and it will be loaded next time netsmain.pl starts.
The Plug-ins are loaded into netsmain.pl after:
Often a Nets Plug-in requires many other files to be ` require 'd or ` use 'd in order to support its features. This can have an impact on the time required for Nets to load and start running. You can reduce the effect of slow loading of large Plug-ins by using deferred loading. Using deferred loading, the Plug-in includes a single function that loads the main part of the Plug-in only when it is needed. You can then put the main part of the Plug-in in a second file (without the .npm) extension) and load it manually when your Plug-in function is called:
# mytestplugin.npm
$main::top->{file_menu}->command
(-label => 'Just testing',
-command => my_test_fn,
);
sub my_test_fn
{
require 'plugins/xxx.pm'; # Deferred loading
return Nets::XXX->new(@_);
}
Nets includes mechanisms for loading and importing data into its SQL database. A Nets Database Load File is a specially formatted data file that inserts and updates records in the Nets SQL database according to the data definition in Schema.pm (see Section 5.1 ).
Database load files such as basicdb.dat in the Nets distribution are used to initially populate the Nets database at installation time. They are also used to create the objects as part of a Template (see Section 9.0 ).
A Database load file can be imported into Nets in any of three ways:
A Load File is an ASCII text file that contains a sequence of multiline records. Here is a typical example:
# Nets database export Tue Mar 7 11:10:41 2000
Type:DEVICETYPE
ID:1
NAME:Cisco 3000
Type:DEVICE
ADDRESS:1
ASSET:A00001
COMMISSIONDATE:936280800
DESCRIPTION:Main router for Melbourne
DEVICETYPE:1
ID:1
INSTALLDATE:933602400
INTERNALTO:
LOCATION:1
MAINTAINER:
MANUFACTURER:
NAME:melcor1
NOTES:Leased from Cisco\nsecond line
OPERATINGSYSTEM:IOS 11.3
PURCHASEDATE:930924000
RACK:
SUPPLIER:
Any line beginning with a hash (`#') is ignored.
The first line specifies the type of record that follows:
The record type must be one of the tables defined by Schema.pm, otherwise the rest of the record will be silently ignored.
The record is terminated by a blank line.
Following the record type line, there is one line for each column value. Columns that are defined in Schema.pm, but which are not present in the record are set to NULL. Columns that are defined in the record, but which are not defined in Schema.pm are silently ignored.
Each column consists of a column name followed by the data for that column:
Any `\n' that appears in the data will be replaced by a newline character.
Most tables in the Nets database are defined in Schema.pm with one column of type `id'. Such ID columns are automatically maintained by Nets so as to ensure that column can serve as a unique identifier for each row in the table. When a database load file is loaded, Nets handles such ID columns specially.
If the load record does not specify a value for the ID column, Nets will automatically allocate a new unique ID for the new row.
If the load record does specify a value for the ID column, Nets will replace any existing row in the database of the same ID with the new record.
This mechanism means that you can choose whether to replace an existing record with the same ID, or to add the new record, regardless of what records are already in the database.
Using the idForName macro, you can also arrange to replace a record where you know the name, but not necessarily the ID:
Type:DEVICETYPE
ID:idForName(`Cisco 3000')
NAME:Cisco 3000
This code will replace any existing row in the DEVICETYPE table that has a NAME column of `Cisco 3000'.
Nets load files permit a number of special macros for automatically setting IDs and foreign keys. These macros are intended to help in setting up relations between records in the SQL database. This allows you to ensure that when you create a DEVICE and its INTERFACES, for example, the DEVICE column in each INTERFACE refers to the ID of the newly created DEVICE. That way you can ensure mutual consistency between all the records created by a load file.
The following macros are supported:
Replaced by the ID of the last record created in the table `tablename' by this load file. If there was no previous record for `tablename' replaced by empty string. For example:
Type:DEVICE
DESCRIPTION:Cisco 3000
.....
Type:INTERFACE
DESCRIPTION:BRI interface for Cisco 3000
ID:lastId(`DEVICE')
.....
Replaced by the ID of the record in `tablename' whose NAME column has the value of `name'. If `tablename' is not specified, it defaults to the table of the record currently being defined. This is especially useful for setting values for foreign key columns (defined as type `fk' in Schema.pm). For example:
Type::DEVICETYPE
NAME:Cisco 3000
Type:DEVICE
DESCRIPTION:Cisco 3000
DEVICETYPE:idForName(`Cisco 3000','DEVICETYPE')
Templates provide an easy way for Nets users to create a number of related objects in the Nets database. A Template is typically used for creating a particular type of DEVICE, along with all its INTERFACES and/or CONNECTORS.
Nets users are encouraged to contribute their Templates so they may be included in future releases for the benefit of other Nets users.
Most of the work of a Template is done by a Nets Database Load File (see Section 8.0 ). But a Template also requires an entry in the Nets TEMPLATES table so that the user can find and select that Template.
The Load file specified by a TEMPLATE is required to exist in the <NetsDir>/templates directory. You can install a template load file in the <NetsDir>/templates directory and also create the TEMPLATES table entry by using the features provided by Packages (see Section 10.0 ).
Although it is possible to automatically create a Template load file from a DEVICE using Nets, a Template that is intended for distribution to other Nets systems should be hand crafted. This is because you need to be sure that any foreign keys are resolved to the correct row in the database.
That usually means that you must use lastId or idForName for any ID columns, and use idForName for all foreign key columns. If you don't do this, there is no guarantee that IDs and foreign keys will specify the correct records.
Packages are a way of combining one or more Nets modifications and extensions into a single easy to distribute and install bundle. A Package is the most common way for third parties to add significant new features to Nets.
A Package is a directory containing a number of files. It must contain a DESCRIPTION file. The DESCRIPTION file contains a description of the package, a list of the files to be installed and actions that are to be performed when the package is installed.
A Package can contain 0 or more of any of the following items:
A Nets Package can be installed by one of two methods:
In either case, installation of a Package follows these steps:
Package DESCRIPTION files are ASCII text files that describe the Package, and specify what files are to be installed where, and what actions are to be taken at install time.
Line beginning with hash (`#') are ignored.
The file consists of a series of "keyword value" lines.
The following keywords are supported:
Specifies the name of this package. This will appear on the Nets Package Installer window when the package is selected, and will also be inserted in the PACKAGE table when the package is installed.
The name of the organization that created this package. This will be inserted in the PACKAGE table when the package is installed.
The revision number of this package This will be inserted in the PACKAGE table when the package is installed.
A brief description of the package. This will be inserted in the PACKAGE table when the package is installed.
This optional keyword alters the source location of any files read or used during Package installation. The default is the same directory where the DESCRIPTION file was found.
This optional keyword specifies a minimum Nets version required to support this package. The package can not be installed into a Nets system with an earlier version number.
Each PreInstall line specifies a Perl file that will be loaded into Nets and executed before any files are installed. The PreInstall files will be run in the order that they appear in the DESCRIPTION file.
Because PreInstall files are loaded into Nets, they have full access to all Nets data and functions. Probably the most important data items are the Nets configuration variables from Site.pm (see Section 5.3 ), and the SQL database access functions in DBSQL.pm (see Section 4.1 ) and DBUtil.pm (see Section 4.2 ).
Specifies a file that is to be installed from the package directory (or InstallBase, if defined) into the current NetsDir. If the file named by from contains a leading path, it will be installed under the same path in NetsDir. For example:
will install the file tnt.dat from the templates directory in the package into <NetsDir>/templates.
If the :to is specified, the file will be installed in the directory named by to in NetsDir. For example:
will install the file xxx from the package directory into <NetsDir>/templates.
Files will be installed in the order in which they appear in the DESCRIPTION file. Any previously existing files with the same name in the target directories will be replaced.
Specifies a file that is to be installed from the package directory (or InstallBase, if defined) into the the directory defined by CgiBinDir in Site.pm.. If the file contains a leading path, it will be installed under the same path in CgiBinDir. For example:
will install the file myscript.pl from the private directory in the package into <CgiBinDir>/private.
If the :to is specified, the file will be installed in the directory named by to in CgiBinDir. For example:
will install the file myscript.pl from the package directory into <CgiBinDir>/private.
Files will be installed in the order in which they appear in the DESCRIPTION file. Any previously existing files with the same name in the target directories will be replaced.
Each PostInstall line specifies a Perl file that will be loaded into Nets and executed after any files have been installed. The PostInstall files will be run in the order that they appear in the DESCRIPTION file.
Because PostInstall files are loaded into Nets, they have full access to all Nets data and functions. Probably the most important data items are the Nets configuration variables from Site.pm (see Section 5.3 ), and the SQL database access functions in DBSQL.pm (see Section 4.1 ) and DBUtil.pm (see Section 4.2
A Nets Package consists of a directory containing a number of files, including at least a DESCRIPTION file.
It is common to want to send a Package to another Nets user, so that they can install the Package into their Nets system. The recommended way of bundling a package is in a gzipped tar file (also known as a tarball or tgz file). The bundle should be set up so that when the recipient untars it, it unpacks the package directory into the current directory. This can best be achieved by tarring the package from the next highest directory level. For example, imagine that you have made a Package that adds new network visualization tools to Nets. The Package consists of a number of file in the directory `visualiser' (including of course the DESCRIPTION file that says what is to be installed and where). If you are currently in the visualiser directory:
$ cd ..
$ tar cvf - visualiser|gzip -c >visualiser.tgz
visualiser/
visualiser/DESCRIPTION
visualiser/.....
.....
$
You can then send the visualiser.tgz file to anyone else to install into their Nets system. The recipient can then unpack and install the package with something like:
$ gunzip -c visualiser.tgz|tar xvf -
visualiser/
visualiser/DESCRIPTION
visualiser/.....
...
$ netspkginstall.pl visualiser
$
Here is an example that installs a new template file into the NetsDir templates file, and then adds a corresponding entry to the TEMPLATES table
# Example Nets package DESCRIPTION file
Name Example Package
Vendor Open System Consultants
Revision 1.1
Description Simple example of a Nets package
NetsDir templates/tnt.dat
PostInstall postinstall.pl
# This is the postinstall perl script, which will be run
# after the files are installed. Adds an entry to TEMPLATES
# using a database load file
&Nets::Util::load
("$main::current_package->{InstallBase}/addtemplate.dat");
# addtemplate.dat
# Adds an entry to the TEMPLATES table
Type:TEMPLATE
DESRIPTION:A sample template which makes an Ascend TNT
FILENAME:tnt.dat
NAME:TNT device
# This template creates a TNT device
Type:DEVICE
DESCRIPTION:Ascend TNT
......
Nets provides a simple scripting language for mechanizing some simple tasks. More complicated tasks are probably better suited to using a Plug-in (see Section 7.0 ).
Scripts can be run using by either of two methods:
Any number of Nets scripts can be running at the same time. Each script runs independently and in parallel with other Nets activities. Scripts are executed one line at a time whenever the Nets main program is otherwise idle.
Nets scripts are ASCII text files containing Nets Scripting Language (NSL) commands. The conventional filename extension is .nsl , but scripts can be given any name you wish.
The following NSL commands are supported:
Creates or raises a Nets window. You can specify a particular type of Nets window to show, or let Nets choose an appropriate editing window for a certain type of Nets object. You can make the Nets window display a particular database object, and control its geometry (i.e. size and position) and title.
The general syntax for show is:
show [class Nets::windowclass] [type tablename] [id nnn] [title sometitle] [geometry WxH+X+Y]
Show looks for an existing window with matching class and type. If one is found, that window will be reconfigured and raised. If no matching window is found, the appropriate Nets::class module will be loaded, and a new window created.
Hint: you can change the preferred editor class for a given object type by using Nets::Session::registerEditorClass.
Similar to show, except that if class is not specified, but type is, Nets will select the preferred lister class for that type of object.
Hint: you can change the preferred lister class for a given object type by using Nets::Session::registerListerClass.
Starts the execution of a Nets script. Does not wait for the new script to complete. The script named must be a file in the <NetsDir>/scripts directory.
Pops up a Nets Package Installer window, ready to install the package in the given directory.
If you need help with Nets development tasks, you should consider using the Nets mailing list, or (if you have a support contract) the Nets support email address.
However, before posting to request information or help, try the following:
If you solve your problem, consider posting a summary and the solution, so we can add it to the Nets FAQ.
If you find a bug,please let us know so we can fix it. The best way to let us know is to post to the Nets mailing list.