~ibmcharmers/xenial/ibm-db2-dae

Owner: shilkaul
Status: Needs Review
Vote: +0 (+2 needed for approval)

CPP?: No
OIL?: No

This charm is for IBM DB2 Direct Advanced Edition.

Its source code can be found in the below repository
Repo : https://code.launchpad.net/~ibmcharmers/charms/xenial/layer-ibm-db2-dae/trunk


Tests

Substrate Status Results Last Updated
aws RETRY 19 days ago
gce RETRY 19 days ago
lxc RETRY 19 days ago

Add Comment

Login to comment/vote on this review.


Policy Checklist

Description Unreviewed Pass Fail

General

Must verify that any software installed or utilized is verified as coming from the intended source.
  • Any software installed from the Ubuntu or CentOS default archives satisfies this due to the apt and yum sources including cryptographic signing information.
  • Third party repositories must be listed as a configuration option that can be overridden by the user and not hard coded in the charm itself.
  • Launchpad PPAs are acceptable as the add-apt-repository command retrieves the keys securely.
  • Other third party repositories are acceptable if the signing key is embedded in the charm.
Must provide a means to protect users from known security vulnerabilities in a way consistent with best practices as defined by either operating system policies or upstream documentation.
Basically, this means there must be instructions on how to apply updates if you use software not from distribution channels.
Must have hooks that are idempotent.
Should be built using charm layers.
Should use Juju Resources to deliver required payloads.

Testing and Quality

charm proof must pass without errors or warnings.
Must include passing unit, functional, or integration tests.
Tests must exercise all relations.
Tests must exercise config.
set-config, unset-config, and re-set must be tested as a minimum
Must not use anything infrastructure-provider specific (i.e. querying EC2 metadata service).
Must be self contained unless the charm is a proxy for an existing cloud service, e.g. ec2-elb charm.
Must not use symlinks.
Bundles must only use promulgated charms, they cannot reference charms in personal namespaces.
Must call Juju hook tools (relation-*, unit-*, config-*, etc) without a hard coded path.
Should include a tests.yaml for all integration tests.

Metadata

Must include a full description of what the software does.
Must include a maintainer email address for a team or individual who will be responsive to contact.
Must include a license. Call the file 'copyright' and make sure all files' licenses are specified clearly.
Must be under a Free license.
Must have a well documented and valid README.md.
Must describe the service.
Must describe how it interacts with other services, if applicable.
Must document the interfaces.
Must show how to deploy the charm.
Must define external dependencies, if applicable.
Should link to a recommend production usage bundle and recommended configuration if this differs from the default.
Should reference and link to upstream documentation and best practices.

Security

Must not run any network services using default passwords.
Must verify and validate any external payload
  • Known and understood packaging systems that verify packages like apt, pip, and yum are ok.
  • wget | sh style is not ok.
Should make use of whatever Mandatory Access Control system is provided by the distribution.
Should avoid running services as root.

Source Diff

Inline diff comments 0

No comments yet.

Back to file index

Makefile

 1
--- 
 2
+++ Makefile
 3
@@ -0,0 +1,24 @@
 4
+#!/usr/bin/make
 5
+
 6
+all: lint unit_test
 7
+
 8
+
 9
+.PHONY: clean
10
+clean:
11
+	@rm -rf .tox
12
+
13
+.PHONY: apt_prereqs
14
+apt_prereqs:
15
+	@# Need tox, but don't install the apt version unless we have to (don't want to conflict with pip)
16
+	@which tox >/dev/null || (sudo apt-get install -y python-pip && sudo pip install tox)
17
+
18
+.PHONY: lint
19
+lint: apt_prereqs
20
+	@tox --notest
21
+	@PATH=.tox/py34/bin:.tox/py35/bin flake8 $(wildcard hooks reactive lib unit_tests tests)
22
+	@charm proof
23
+
24
+.PHONY: unit_test
25
+unit_test: apt_prereqs
26
+	@echo Starting tests...
27
+	tox
Back to file index

README.md

  1
--- 
  2
+++ README.md
  3
@@ -0,0 +1,185 @@
  4
+Charm for IBM DB2 Direct Advanced Edition 11.1.1.1
  5
+
  6
+Overview
  7
+--------
  8
+
  9
+IBM DB2 Direct Advanced Edition
 10
+
 11
+IBM DB2 Direct Advanced Edition introduce a set of new license metrics to facilitate hybrid cloud deployments. The DB2 Direct Editions provide the same DB2 functionality but add ease of purchase and licensing flexibility using a newly introduced simplified license metric, the Virtual Processor Core (VPC) sold as a monthly license charge. Clients can acquire the product directly online and have the option to deploy either on- premises or on cloud. 
 12
+For details on DB2 Direct Advanced Edition, as well as information on purchasing, please visit:
 13
+[Product Page][product-page-dae].
 14
+
 15
+More information available at the [IBM Knowledge Center][db2-knowledgecenter]
 16
+
 17
+Usage
 18
+-----
 19
+The charm installs `DB2 Version 11.1 Mod1 Fix pack1` as there are installation issues on Ubuntu Z if we install Base Version `11.1.0`. To get this version ie `11.1.1.1`, user needs to download the required packages from [IBM Fix Central][fix-central] site. 
 20
+User also needs to download the `Activation key` for IBM DB2 Direct Advanced Edition. Each DB2 database product has its own license key. User can download the license key from [Passport Advantage][passport-advantage] site.
 21
+The part number for `IBM DB2 Direct Advanced Edition 11.1.1.1 Activation Key` is `CNGC5ML`.
 22
+
 23
+To install the downloaded binaries you must agree to the IBM license. You can view the full license for DB2 DAE by visiting the [Software license agreements search website][license-info]. Search for `"DB2 Direct Advanced Edition 11.1.1.1"` and choose the license that applies to the version you are using.
 24
+
 25
+In case you already have an IBM account and cannot download the product or for other error during SW download, please refer to the [IBM Support Site][ibm-support] to solve the error.
 26
+
 27
+Memory and Disk Requirements
 28
+----------------------------
 29
+At a minimum, a DB2 database system requires 256 MB of RAM. For a system running just a DB2 product and the DB2 GUI tools, a minimum of 512 MB of RAM is required. However, 1 GB of RAM is recommended for improved performance.
 30
+
 31
+On Linux and UNIX operating systems, 2 GB of free space in the /tmp directory is recommended. Please make sure this minimum memory configuration is available before deploying the charm. More information on this can be found in [Memory Requirements][db2-memory-disk-requirement]
 32
+
 33
+Deploy
 34
+------
 35
+To deploy DB2-DAE charm, run the following command:
 36
+**Note : Make sure the appropriate memory requirements are made available.**
 37
+    
 38
+    juju deploy ibm-db2-dae --resource ibm_db2_dae_installer=</path/to/installer.tar.gz> --resource ibm_db2_dae_license=</path/to/license.zip> 
 39
+Note: This charm requires acceptance of Terms of Use. When deploying from the Charm Store, these terms will be presented to you for your consideration.
 40
+To accept the terms:
 41
+    
 42
+    juju agree ibm-db2-dae/1
 43
+Once you have agreed to the Terms, then only the IBM DB2 Direct Advanced Edition charm will be deployed.
 44
+Juju deploy command will install db2 and will expose the hostname, port number, db2 instance, install path  and userid to the users. 
 45
+
 46
+
 47
+Additional configuration parameters 
 48
+-----------------------------------
 49
+
 50
+Following shows the different configurable values for ibm-db2-dae charm:
 51
+ 
 52
+* If the user wants to set a different file path used to create databases and logs it can be set using the config value dftdbpath. Use the following command to set it
 53
+
 54
+        juju set ibm-db2-dae dftdbpath=<new-path-to-set>
 55
+
 56
+    For eg:
 57
+
 58
+        juju set ibm-db2-dae dftdbpath="/tmp"
 59
+
 60
+
 61
+Installation Verification
 62
+------------------------
 63
+Once IBM DB2 DAE charm is deployed, the user can log into the container/machine where it is deployed using the default user(`db2inst1`). The user can run any db2 commands after this. 
 64
+  
 65
+  * For creating a new DB the user may run the command:
 66
+
 67
+        db2 create database <db-name>
 68
+
 69
+  * For listing the DBs created, run the command:
 70
+        
 71
+        db2 list db directory
 72
+
 73
+  * For getting db2 command prompt just run the command:
 74
+
 75
+        db2
 76
+
 77
+Relating with other consumer charms
 78
+----------------------------------
 79
+IBM DB2 DAE charm can be related to other consumer charms using the following command.
 80
+
 81
+    juju add-relation ibm-db2-dae <consumer-charm>
 82
+
 83
+When IBM DB2 DAE charm is related to any consumer charm, it creates a db2instance, username/password as per the service name and will be provided to the consumer charm. IBM DB2 DAE charm also creates DBs as provided by the consumer charm and returns the DB details once they are successfully created. The following code will help the consumer charm authors to pass the DB names to the IBM DB2 DAE charm:   
 84
+
 85
+    @when 'db.connected'
 86
+    function configure_dbs(){
 87
+      dbnames="db1,db2"
 88
+      relation_call --state=db.connected set_dbs $dbnames || true
 89
+     }
 90
+
 91
+If no DB name is provided by consumer charm, IBM DB2 DAE charm by default creates DBs according to  the service name.
 92
+
 93
+Also to set relation with IBM DB2 DAE charm and make use of all the features, the consumer charm __should__ pass the ssh key from itself to IBM DB2 DAE charm. The following code will help the consumer charm authors to do this :
 94
+
 95
+     @when 'db.connected'
 96
+     @when_not 'test.sshconfigured'
 97
+     function configure_sshkeys(){
 98
+     SSH_PATH=/root/.ssh
 99
+     if [ ! -f  $SSH_PATH/id_rsa.pub ]; then
100
+                juju-log "Setting up SSH keys."
101
+                ssh-keygen -t rsa -f $SSH_PATH/id_rsa -N ''
102
+     fi
103
+     key="`cat $SSH_PATH/id_rsa.pub`"
104
+     relation_call --state=db.connected set_ssh_keys $key || true`
105
+     set_state 'test.sshconfigured'
106
+    }
107
+
108
+Without this IBM DB2 DAE charm will not be ready and will not create the DBs for the related services. 
109
+
110
+Configuration
111
+-------------
112
+See config.yaml file for more information.
113
+  
114
+  * `dftdbpath`             : This parameter contains the default file path used to create databases under the database manager.  If no path is specified when a database is created, the database is created under the path specified by the dftdbpath parameter.
115
+
116
+Additional product information
117
+------------------------------
118
+
119
+##### Enabling BLU acceleration for DB2 Direct Advanced Edition (DAE)
120
+
121
+The DB2-DAE charm has to be deployed first and then few settings need to be done to enable the BLU feature. 
122
+To enable the BLU feature the DB2_WORKLOAD registry variable has to be set to ANALYTICS and then the DB has to be restarted. The following commands will help the user for this.
123
+
124
+    db2set DB2_WORKLOAD=ANALYTICS
125
+    db2stop force
126
+    db2start
127
+    
128
+To test that DB2 DAE with BLU acceleration is enabled run the following command:
129
+    
130
+    db2 create database <test-db>
131
+    db2 connect to <test-db> 
132
+    db2 get db cfg | grep DFT_TABLE_ORG
133
+    
134
+The output Default table organization              (DFT_TABLE_ORG) = COLUMN confirms that the DB2 DAE with BLU is enabled. If the pre requisites for DB2-DAE is not set (setting the registry variable DB2_WORKLOAD) the above command would return Default table organization              (DFT_TABLE_ORG) = ROW.  Column-organized tables store each column on a separate set of pages on disk. Organizing data by column on disk reduces the amount of I/O needed for processing queries because only columns that are referenced in a query need to be accessed. 
135
+
136
+Once this is set all the tables created will be by default COLUMN organized whereas without BLU acceleration the tables will be ROW organized. Also without proper license we cannot create COLUMN organized tables. Once we enable COLUMN organized tables, we can create either ROW enabled or COLUMN enabled tables using the option ORGANIZE BY ROW or ORGANIZE BY COLUMN while creating the tables by running the below commands from db2 command prompt.
137
+
138
+    create table sales_row(tid integer not null, prod_name varchar(30)) ORGANIZE BY ROW
139
+    create table sales_col(tid integer not null, prod_name varchar(30)) ORGANIZE BY COLUMN
140
+
141
+    
142
+More details on BLU feature can be found in the link [db2-BLU-acceleration]
143
+
144
+IBM DB2 Limitations
145
+-------------------
146
+If you are running linux containers on a host with kernel < 3.16, be advised that db2start will not succeed because of a hard coded 32MB kernel.shmmax setting.  You will need to upgrade your host to kernel 3.16 or greater by following the instructions here:
147
+
148
+https://wiki.ubuntu.com/Kernel/LTSEnablementStack
149
+
150
+DB2 also needs to be deployed using a non-zfs filesystem for container deployment. ZFS file system might cause some of the db2 commands to error out.
151
+
152
+IBM DB2 Links and Contacts
153
+--------------------------
154
+
155
+(1) General Information
156
+Information on IBM DB2 available at the [DB2 Knowledgecenter][db2-knowledgecenter]
157
+
158
+(2) Download Information
159
+Information on procuring DB2 product is available at the [Passport Advantage Site][passport-advantage]
160
+
161
+(3) Contact Information
162
+For issues with this charm, please contact <jujusupp@us.ibm.com>
163
+
164
+
165
+<!-- Links -->
166
+
167
+[product-page-dae]: http://www-03.ibm.com/software/products/en/ibm-db2-direct-advanced-edition
168
+
169
+[fix-central]: https://www-945.ibm.com/support/fixcentral/swg/selectFixes?parent=ibm~Information%2BManagement&product=ibm/Information+Management/DB2&release=11.1.*&platform=All&function=fixId&fixids=*server_t*FP001*&includeSupersedes=0&source=fc
170
+
171
+[passport-advantage]: http://www.ibm.com/software/howtobuy/passportadvantage
172
+
173
+[license-info]: http://www-03.ibm.com/software/sla/sladb.nsf/search
174
+
175
+[db2-knowledgecenter]: https://www.ibm.com/support/knowledgecenter/en/SSEPGG_11.1.0/com.ibm.db2.luw.licensing.doc/doc/r0053238.html
176
+
177
+[ibm-support]: https://www-947.ibm.com/support/entry/myportal/support
178
+
179
+[db2-BLU-acceleration]: http://www.ibm.com/developerworks/data/library/techarticle/dm-1309db2bluaccel/
180
+
181
+[db2-memory-disk-requirement]: https://www.ibm.com/support/knowledgecenter/en/SSEPGG_11.1.0/com.ibm.db2.luw.qb.server.doc/doc/r0008877.html
182
+
183
+
184
+
185
+
186
+
187
+
188
+
Back to file index

bin/layer_option

 1
--- 
 2
+++ bin/layer_option
 3
@@ -0,0 +1,24 @@
 4
+#!/usr/bin/env python3
 5
+
 6
+import sys
 7
+sys.path.append('lib')
 8
+
 9
+import argparse
10
+from charms.layer import options
11
+
12
+
13
+parser = argparse.ArgumentParser(description='Access layer options.')
14
+parser.add_argument('section',
15
+                    help='the section, or layer, the option is from')
16
+parser.add_argument('option',
17
+                    help='the option to access')
18
+
19
+args = parser.parse_args()
20
+value = options(args.section).get(args.option, '')
21
+if isinstance(value, bool):
22
+    sys.exit(0 if value else 1)
23
+elif isinstance(value, list):
24
+    for val in value:
25
+        print(val)
26
+else:
27
+    print(value)
Back to file index

config.yaml

 1
--- 
 2
+++ config.yaml
 3
@@ -0,0 +1,8 @@
 4
+"options":
 5
+  "dftdbpath":
 6
+    "type": "string"
 7
+    "default": "/tmp"
 8
+    "description": |
 9
+      This parameter contains the default file path used to create databases under
10
+      the database manager.  If no path is specified when a database is created, the
11
+      database is created under the path specified by the dftdbpath parameter.
Back to file index

copyright

 1
--- 
 2
+++ copyright
 3
@@ -0,0 +1,13 @@
 4
+Copyright 2017 IBM Corporation
 5
+
 6
+This Charm is licensed under the Apache License, Version 2.0 (the "License");
 7
+you may not use this file except in compliance with the License.
 8
+You may obtain a copy of the License at
 9
+
10
+    http://www.apache.org/licenses/LICENSE-2.0
11
+
12
+Unless required by applicable law or agreed to in writing, software
13
+distributed under the License is distributed on an "AS IS" BASIS,
14
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+See the License for the specific language governing permissions and
16
+limitations under the License.
Back to file index

files/archives/db2inst1.INS

  1
--- 
  2
+++ files/archives/db2inst1.INS
  3
@@ -0,0 +1,119 @@
  4
+;Use BINARY file transfer
  5
+
  6
+[FILE_DESCRIPTION]
  7
+APPLICATION=DB2/LINUXX8664 0.5.3
  8
+FILE_CONTENT=DB2 CCA Exported Data Sources
  9
+FILE_TYPE=CommonServer
 10
+FILE_FORMAT_VERSION=2.0
 11
+Platform=30
 12
+DB2SYSTEM=ISLRPBEIXV665
 13
+Instance=db2inst1
 14
+
 15
+[REGISTRY_LOCAL]
 16
+DB2COMM=TCPIP
 17
+DB2AUTOSTART=NO
 18
+
 19
+[DBM_CONFIG]
 20
+NODETYPE=4
 21
+RELEASE=0x1000
 22
+DIAGLEVEL=3
 23
+ALTERNATE_AUTH_ENC=255
 24
+RQRIOBLK=65535
 25
+AUTHENTICATION=0
 26
+DIR_CACHE=1
 27
+DISCOVER=2
 28
+TP_MON_NAME=
 29
+SYSADM_GROUP=DB2GRP1 
 30
+SYSCTRL_GROUP=
 31
+SYSMAINT_GROUP=
 32
+SYSMON_GROUP=
 33
+TM_DATABASE=1ST_CONN
 34
+DFT_ACCOUNT_STR=
 35
+CATALOG_NOAUTH=0
 36
+NOTIFYLEVEL=3
 37
+JAVA_HEAP_SZ=2048
 38
+FEDERATED=0
 39
+FED_NOAUTH=0
 40
+UTIL_IMPACT_LIM=10
 41
+GROUP_PLUGIN=
 42
+CLNT_PW_PLUGIN=
 43
+CLNT_KRB_PLUGIN=
 44
+LOCAL_GSSPLUGIN=
 45
+MAX_QUERYDEGREE=-1
 46
+AUDIT_BUF_SZ=0
 47
+INTRA_PARALLEL=0
 48
+NUMDB=32
 49
+INITFENCED_JVM=0
 50
+INDEXREC=2
 51
+SHEAPTHRES=0
 52
+BACKBUFSZ=1024
 53
+RESTBUFSZ=1024
 54
+ASLHEAPSZ=15
 55
+FENCED_POOL=AUTOMATIC-1
 56
+KEEPFENCED=1
 57
+AGENTPRI=-1
 58
+SSL_SVR_KEYDB=
 59
+SSL_SVR_STASH=
 60
+SSL_SVR_LABEL=
 61
+SSL_SVCENAME=
 62
+SSL_CIPHERSPECS=
 63
+SSL_VERSIONS=
 64
+SSL_CLNT_KEYDB=
 65
+SSL_CLNT_STASH=
 66
+DFT_MON_UOW=OFF
 67
+DFT_MON_STMT=OFF
 68
+DFT_MON_TABLE=OFF
 69
+DFT_MON_BUFPOOL=OFF
 70
+DFT_MON_LOCK=OFF
 71
+DFT_MON_SORT=OFF
 72
+DFT_MON_TIMESTAMP=ON
 73
+CPUSPEED=1.889377e-07
 74
+MAXTOTFILOP=0
 75
+AGENT_STACK_SZ=1024
 76
+MON_HEAP_SZ=AUTOMATIC90
 77
+RESYNC_INTERVAL=180
 78
+SPM_LOG_FILE_SZ=256
 79
+SPM_MAX_RESYNC=20
 80
+TRUST_ALLCLNTS=YES
 81
+NUM_INITFENCED=0
 82
+SPM_NAME=islrpbei
 83
+NUM_INITAGENTS=0
 84
+MAX_COORDAGENTS=AUTOMATIC200
 85
+NUM_POOLAGENTS=AUTOMATIC100
 86
+FCM_NUM_BUFFERS=4096
 87
+FCM_NUM_CHANNELS=AUTOMATIC2048
 88
+DISCOVER_INST=1
 89
+MAX_CONNECTIONS=AUTOMATIC-1
 90
+INSTANCE_MEMORY=AUTOMATIC1698252
 91
+HEALTH_MON=OFF
 92
+SRV_PLUGIN_MODE=1
 93
+SRVCON_PW_PLUGIN=
 94
+SRVCON_GSSPLUGIN_LIST=
 95
+COMM_BANDWIDTH=1.000000e+02
 96
+CONN_ELAPSE=10
 97
+MAX_CONNRETRIES=5
 98
+MAX_TIME_DIFF=60
 99
+START_STOP_TIME=10
100
+FEDERATED_ASYNC=0
101
+
102
+[INST>db2inst1]
103
+instance_name=db2inst1
104
+NodeType=4
105
+ServerType=DB2LINUXX8664
106
+Authentication=SERVER
107
+DB2COMM=TCPIP
108
+
109
+[DB>!LOCAL:APPCNTR]
110
+Dir_entry_type=INDIRECT
111
+Drive=/home/db2inst1
112
+DBName=APPCNTR
113
+
114
+[DB>!LOCAL:WRKLGHT]
115
+Dir_entry_type=INDIRECT
116
+Drive=/home/db2inst1
117
+DBName=WRKLGHT
118
+
119
+[DB>!LOCAL:TUT_DB]
120
+Dir_entry_type=INDIRECT
121
+Drive=/home/db2inst1
122
+DBName=TUT_DB
Back to file index

files/archives/db2server_z.rsp

 1
--- 
 2
+++ files/archives/db2server_z.rsp
 3
@@ -0,0 +1,72 @@
 4
+*--------------------------------------------------------
 5
+* The response file is generated by the db2rspgn command 
 6
+*--------------------------------------------------------
 7
+*--------------------------
 8
+* Product Installation
 9
+*--------------------------
10
+PROD = DB2_SERVER_EDITION
11
+FILE = /opt/ibm/db2/V11.1
12
+LIC_AGREEMENT = ACCEPT
13
+INSTALL_TYPE = CUSTOM
14
+COMP = BASE_CLIENT
15
+COMP = JAVA_SUPPORT
16
+COMP = SQL_PROCEDURES
17
+COMP = BASE_DB2_ENGINE
18
+COMP = ODBC_DATA_SOURCE_SUPPORT
19
+COMP = TERADATA_DATA_SOURCE_SUPPORT
20
+COMP = IINR_SCIENTIFIC_WRAPPER
21
+COMP = JDBC_DATA_SOURCE_SUPPORT
22
+COMP = JDK
23
+COMP = IINR_STRUCTURED_FILES_WRAPPER
24
+COMP = ORACLE_DATA_SOURCE_SUPPORT
25
+COMP = CONNECT_SUPPORT
26
+COMP = IINR_APPLICATIONS_WRAPPER
27
+COMP = SQL_SERVER_DATA_SOURCE_SUPPORT
28
+COMP = COMMUNICATION_SUPPORT_TCPIP
29
+COMP = REPL_CLIENT
30
+COMP = DB2_DATA_SOURCE_SUPPORT
31
+COMP = SPATIAL_EXTENDER_SERVER_SUPPORT
32
+COMP = LDAP_EXPLOITATION
33
+COMP = INSTANCE_SETUP_SUPPORT
34
+COMP = SPATIAL_EXTENDER_CLIENT_SUPPORT
35
+COMP = APPLICATION_DEVELOPMENT_TOOLS
36
+COMP = FED_DATA_SOURCE_SUPPORT
37
+COMP = DB2_UPDATE_SERVICE
38
+COMP = FIRST_STEPS
39
+COMP = DB2_SAMPLE_DATABASE
40
+COMP = TEXT_SEARCH
41
+COMP = GUARDIUM_INST_MNGR_CLIENT
42
+COMP = INFORMIX_DATA_SOURCE_SUPPORT
43
+*--------------------------
44
+* Installed Languages
45
+*--------------------------
46
+LANG = EN
47
+INSTALL_ENCRYPTION = YES
48
+*--------------------------
49
+* Instance Properties
50
+*--------------------------
51
+INSTANCE = db2inst1
52
+db2inst1.NAME = db2inst1
53
+db2inst1.UID = db2inst1_uid
54
+db2inst1.GROUP_NAME = db2grp1
55
+db2inst1.GID = db2inst1_gid
56
+db2inst1.HOME_DIRECTORY = /home/db2inst1_homedir
57
+db2inst1.PASSWORD = db2inst1_password
58
+db2inst1.CLIENT_IMPORT_PROFILE = db2inst1.INS
59
+db2inst1.TYPE = ese
60
+db2inst1.FENCED_USERNAME = db2fenc1
61
+db2inst1.FENCED_UID = db2fenc1_uid
62
+db2inst1.FENCED_GROUP_NAME = db2fgrp1
63
+db2inst1.FENCED_GID = db2fenc1_gid
64
+db2inst1.FENCED_HOME_DIRECTORY = /home/db2fenc1
65
+db2inst1.FENCED_PASSWORD = db2fenc1
66
+db2inst1.CONFIGURE_TEXT_SEARCH = NO
67
+*--------------------------
68
+* DAS Properties
69
+*__________________________
70
+DAS_USERNAME = dasusr1
71
+DAS_UID = das_uid
72
+DAS_GROUP_NAME = dasadm1
73
+DAS_GID = das_gid
74
+DAS_HOME_DIRECTORY = /home/dasusr1
75
+DAS_PASSWORD = dasusr1
Back to file index

hooks/config-changed

 1
--- 
 2
+++ hooks/config-changed
 3
@@ -0,0 +1,19 @@
 4
+#!/usr/bin/env python3
 5
+
 6
+# Load modules from $CHARM_DIR/lib
 7
+import sys
 8
+sys.path.append('lib')
 9
+
10
+from charms.layer import basic
11
+basic.bootstrap_charm_deps()
12
+basic.init_config_states()
13
+
14
+
15
+# This will load and run the appropriate @hook and other decorated
16
+# handlers from $CHARM_DIR/reactive, $CHARM_DIR/hooks/reactive,
17
+# and $CHARM_DIR/hooks/relations.
18
+#
19
+# See https://jujucharms.com/docs/stable/authors-charm-building
20
+# for more information on this pattern.
21
+from charms.reactive import main
22
+main()
Back to file index

hooks/db-relation-broken

 1
--- 
 2
+++ hooks/db-relation-broken
 3
@@ -0,0 +1,19 @@
 4
+#!/usr/bin/env python3
 5
+
 6
+# Load modules from $CHARM_DIR/lib
 7
+import sys
 8
+sys.path.append('lib')
 9
+
10
+from charms.layer import basic
11
+basic.bootstrap_charm_deps()
12
+basic.init_config_states()
13
+
14
+
15
+# This will load and run the appropriate @hook and other decorated
16
+# handlers from $CHARM_DIR/reactive, $CHARM_DIR/hooks/reactive,
17
+# and $CHARM_DIR/hooks/relations.
18
+#
19
+# See https://jujucharms.com/docs/stable/authors-charm-building
20
+# for more information on this pattern.
21
+from charms.reactive import main
22
+main()
Back to file index

hooks/db-relation-changed

 1
--- 
 2
+++ hooks/db-relation-changed
 3
@@ -0,0 +1,19 @@
 4
+#!/usr/bin/env python3
 5
+
 6
+# Load modules from $CHARM_DIR/lib
 7
+import sys
 8
+sys.path.append('lib')
 9
+
10
+from charms.layer import basic
11
+basic.bootstrap_charm_deps()
12
+basic.init_config_states()
13
+
14
+
15
+# This will load and run the appropriate @hook and other decorated
16
+# handlers from $CHARM_DIR/reactive, $CHARM_DIR/hooks/reactive,
17
+# and $CHARM_DIR/hooks/relations.
18
+#
19
+# See https://jujucharms.com/docs/stable/authors-charm-building
20
+# for more information on this pattern.
21
+from charms.reactive import main
22
+main()
Back to file index

hooks/db-relation-departed

 1
--- 
 2
+++ hooks/db-relation-departed
 3
@@ -0,0 +1,19 @@
 4
+#!/usr/bin/env python3
 5
+
 6
+# Load modules from $CHARM_DIR/lib
 7
+import sys
 8
+sys.path.append('lib')
 9
+
10
+from charms.layer import basic
11
+basic.bootstrap_charm_deps()
12
+basic.init_config_states()
13
+
14
+
15
+# This will load and run the appropriate @hook and other decorated
16
+# handlers from $CHARM_DIR/reactive, $CHARM_DIR/hooks/reactive,
17
+# and $CHARM_DIR/hooks/relations.
18
+#
19
+# See https://jujucharms.com/docs/stable/authors-charm-building
20
+# for more information on this pattern.
21
+from charms.reactive import main
22
+main()
Back to file index

hooks/db-relation-joined

 1
--- 
 2
+++ hooks/db-relation-joined
 3
@@ -0,0 +1,19 @@
 4
+#!/usr/bin/env python3
 5
+
 6
+# Load modules from $CHARM_DIR/lib
 7
+import sys
 8
+sys.path.append('lib')
 9
+
10
+from charms.layer import basic
11
+basic.bootstrap_charm_deps()
12
+basic.init_config_states()
13
+
14
+
15
+# This will load and run the appropriate @hook and other decorated
16
+# handlers from $CHARM_DIR/reactive, $CHARM_DIR/hooks/reactive,
17
+# and $CHARM_DIR/hooks/relations.
18
+#
19
+# See https://jujucharms.com/docs/stable/authors-charm-building
20
+# for more information on this pattern.
21
+from charms.reactive import main
22
+main()
Back to file index

hooks/hook.template

 1
--- 
 2
+++ hooks/hook.template
 3
@@ -0,0 +1,19 @@
 4
+#!/usr/bin/env python3
 5
+
 6
+# Load modules from $CHARM_DIR/lib
 7
+import sys
 8
+sys.path.append('lib')
 9
+
10
+from charms.layer import basic
11
+basic.bootstrap_charm_deps()
12
+basic.init_config_states()
13
+
14
+
15
+# This will load and run the appropriate @hook and other decorated
16
+# handlers from $CHARM_DIR/reactive, $CHARM_DIR/hooks/reactive,
17
+# and $CHARM_DIR/hooks/relations.
18
+#
19
+# See https://jujucharms.com/docs/stable/authors-charm-building
20
+# for more information on this pattern.
21
+from charms.reactive import main
22
+main()
Back to file index

hooks/install

 1
--- 
 2
+++ hooks/install
 3
@@ -0,0 +1,19 @@
 4
+#!/usr/bin/env python3
 5
+
 6
+# Load modules from $CHARM_DIR/lib
 7
+import sys
 8
+sys.path.append('lib')
 9
+
10
+from charms.layer import basic
11
+basic.bootstrap_charm_deps()
12
+basic.init_config_states()
13
+
14
+
15
+# This will load and run the appropriate @hook and other decorated
16
+# handlers from $CHARM_DIR/reactive, $CHARM_DIR/hooks/reactive,
17
+# and $CHARM_DIR/hooks/relations.
18
+#
19
+# See https://jujucharms.com/docs/stable/authors-charm-building
20
+# for more information on this pattern.
21
+from charms.reactive import main
22
+main()
Back to file index

hooks/leader-elected

 1
--- 
 2
+++ hooks/leader-elected
 3
@@ -0,0 +1,19 @@
 4
+#!/usr/bin/env python3
 5
+
 6
+# Load modules from $CHARM_DIR/lib
 7
+import sys
 8
+sys.path.append('lib')
 9
+
10
+from charms.layer import basic
11
+basic.bootstrap_charm_deps()
12
+basic.init_config_states()
13
+
14
+
15
+# This will load and run the appropriate @hook and other decorated
16
+# handlers from $CHARM_DIR/reactive, $CHARM_DIR/hooks/reactive,
17
+# and $CHARM_DIR/hooks/relations.
18
+#
19
+# See https://jujucharms.com/docs/stable/authors-charm-building
20
+# for more information on this pattern.
21
+from charms.reactive import main
22
+main()
Back to file index

hooks/leader-settings-changed

 1
--- 
 2
+++ hooks/leader-settings-changed
 3
@@ -0,0 +1,19 @@
 4
+#!/usr/bin/env python3
 5
+
 6
+# Load modules from $CHARM_DIR/lib
 7
+import sys
 8
+sys.path.append('lib')
 9
+
10
+from charms.layer import basic
11
+basic.bootstrap_charm_deps()
12
+basic.init_config_states()
13
+
14
+
15
+# This will load and run the appropriate @hook and other decorated
16
+# handlers from $CHARM_DIR/reactive, $CHARM_DIR/hooks/reactive,
17
+# and $CHARM_DIR/hooks/relations.
18
+#
19
+# See https://jujucharms.com/docs/stable/authors-charm-building
20
+# for more information on this pattern.
21
+from charms.reactive import main
22
+main()
Back to file index

hooks/relations/db2/README.md

 1
--- 
 2
+++ hooks/relations/db2/README.md
 3
@@ -0,0 +1,66 @@
 4
+# Overview
 5
+
 6
+This interface layer handles the communication between IBM DB2 and Consumer
 7
+charms. The provider end of this interface provides the IBM DB2 service. The
 8
+consumer part requires the existence of a provider to function.
 9
+
10
+## Usage
11
+
12
+### Provides
13
+
14
+This interface layer will set the following states, as appropriate:
15
+
16
+- `{relation_name}.connected`: The relation is established, but IBM DB2 may not
17
+yet have provided any connection or service information.
18
+
19
+- `{relation_name}.sshconfigured`: A consumer ssh key has been added to the
20
+IBM DB2 `authorized_keys` file.
21
+
22
+- `{relation_name}.ready`: IBM DB2 has established relation with the consumer
23
+charm and the SSH key has been exchanged. DB2 has provided its connection
24
+string information, and is ready to accept requests from the consumer.
25
+
26
+- `{relation_name}.departed`: The relation has been removed. Any cleanup
27
+related to the consumer charm should happen now on the IBM DB2 charm since the
28
+consumer is going away.
29
+
30
+
31
+### Requires
32
+
33
+Consumers like WAS, Mobile First Server, etc require this interface to connect
34
+to IBM DB2. This interface layer will set the following states, as appropriate:
35
+
36
+- `{relation_name}.connected`: The consumer charm has been related to IBM DB2.
37
+At this point, the consumer charm sends the SSH key to IBM DB2 charm.
38
+
39
+    For example, the consumer charm can send the ssh key to IBM DB2 charm as follows:
40
+
41
+    ```
42
+    @when 'db.connected'
43
+    @when_not 'db.sshconfigured'
44
+    function configure_sshkeys_dbs() {
45
+        SSH_PATH=/root/.ssh
46
+        if [ ! -f  $SSH_PATH/id_rsa.pub ]; then
47
+                juju-log "Setting up SSH keys."
48
+                ssh-keygen -t rsa -f $SSH_PATH/id_rsa -N ''
49
+        fi
50
+        key="`cat $SSH_PATH/id_rsa.pub`"
51
+        relation_call --state=db.connected set_ssh_keys "$key" || true
52
+    }
53
+    ```
54
+
55
+-  `{relation_name}.ready`: IBM DB2 is ready to send connection information.
56
+The consumer charm can access the IBM DB2 details from the interface using the
57
+following methods:
58
+
59
+   - get_db2_hostname() - host name of IBM DB2
60
+   - get_db2_port() - port number of IBM DB2
61
+   - get_db2_path() - the install location of IBM DB2
62
+   - get_dbusername() - User name created for the consumer service to connect to DB2
63
+   - get_dbuserpw() - Password for connecting to DB2
64
+   - get_db2_instance_name() - Instance name created for the consumer service
65
+
66
+
67
+- `{relation_name}.departed`: The relation has been removed. Any cleanup
68
+related to IBM DB2 should happen now on the consumer charm since IBM DB2 is
69
+going away.
Back to file index

hooks/relations/db2/interface.yaml

1
--- 
2
+++ hooks/relations/db2/interface.yaml
3
@@ -0,0 +1,4 @@
4
+name: db2
5
+summary: Facilitates communication between IBM DB2 and database consumers
6
+version: 1
7
+maintainer: "IBM Juju Support Team <jujusupp@us.ibm.com>"
Back to file index

hooks/relations/db2/provides.py

 1
--- 
 2
+++ hooks/relations/db2/provides.py
 3
@@ -0,0 +1,88 @@
 4
+from charms.reactive import hook
 5
+from charms.reactive import RelationBase
 6
+from charms.reactive import scopes
 7
+
 8
+
 9
+class db2Provides(RelationBase):
10
+    # Every unit connecting will get the same information
11
+    scope = scopes.SERVICE
12
+    # convenient way to provide accessor methods
13
+    auto_accessors = ['db2_path', 'db2_port']
14
+
15
+    @hook('{provides:db2}-relation-joined')
16
+    def joined(self):
17
+        conversation = self.conversation()
18
+        conversation.remove_state('{relation_name}.departed')
19
+        conversation.set_state('{relation_name}.connected')
20
+
21
+    @hook('{provides:db2}-relation-changed')
22
+    def changed(self):
23
+        conversation = self.conversation()
24
+        conversation.remove_state('{relation_name}.departed')
25
+        conversation.set_state('{relation_name}.connected')
26
+        if str(conversation.get_remote('ssh_key')) != "None":
27
+            conversation.set_state('{relation_name}.ready')
28
+
29
+    @hook('{provides:db2}-relation-departed')
30
+    def departed(self):
31
+        conversation = self.conversation()
32
+        conversation.remove_state('{relation_name}.connected')
33
+        conversation.remove_state('{relation_name}.ready')
34
+        conversation.set_state('{relation_name}.departed')
35
+
36
+    def dismiss(self, service):
37
+        conversation = self.conversation(service)
38
+        conversation.remove_state('{relation_name}.departed')
39
+
40
+    def reset_states(self, service):
41
+        conversation = self.conversation(service)
42
+        conversation.remove_state('{relation_name}.connected')
43
+        conversation.remove_state('{relation_name}.departed')
44
+        conversation.remove_state('{relation_name}.ready')
45
+
46
+    def set_db_details(self, service, db2_path, db2_port, hostname,
47
+                       dbusername, dbuserpw, db2_instance_name, dbs_created):
48
+        conversation = self.conversation(service)
49
+        conversation.set_remote(data={
50
+            'db2_ready': True,
51
+            'db2_path': db2_path,
52
+            'db2_port': db2_port,
53
+            'hostname': hostname,
54
+            'dbusername': dbusername,
55
+            'dbuserpw': dbuserpw,
56
+            'db2_instance_name': db2_instance_name,
57
+            'dbs_created': dbs_created,
58
+        })
59
+
60
+    def set_db_password(self, service, dbuserpw):
61
+        conversation = self.conversation(service)
62
+        conversation.set_local('dbuserpw', dbuserpw)
63
+
64
+    def get_db_password(self, service):
65
+        conversation = self.conversation(service)
66
+        return conversation.get_local('dbuserpw')
67
+
68
+    def set_sshconfigured(self, service):
69
+        conversation = self.conversation(service)
70
+        conversation.set_state('{relation_name}.sshconfigured')
71
+
72
+    def dismiss_sshconfigured(self, service):
73
+        conversation = self.conversation(service)
74
+        conversation.remove_state('{relation_name}.sshconfigured')
75
+
76
+    def get_sshkeys(self, service):
77
+        conversation = self.conversation(service)
78
+        return conversation.get_remote('ssh_key')
79
+
80
+    def get_dbnames(self, service):
81
+        conversation = self.conversation(service)
82
+        return conversation.get_remote('db_names')
83
+
84
+    def services(self):
85
+        """
86
+        Return a list of services requesting databases.
87
+        """
88
+        service = []
89
+        for conversation in self.conversations():
90
+            service.append(conversation.scope)
91
+        return service
Back to file index

hooks/relations/db2/requires.py

 1
--- 
 2
+++ hooks/relations/db2/requires.py
 3
@@ -0,0 +1,65 @@
 4
+# Licensed under the Apache License, Version 2.0 (the "License");
 5
+# you may not use this file except in compliance with the License.
 6
+# You may obtain a copy of the License at
 7
+#
 8
+#     http://www.apache.org/licenses/LICENSE-2.0
 9
+#
10
+# Unless required by applicable law or agreed to in writing, software
11
+# distributed under the License is distributed on an "AS IS" BASIS,
12
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+# See the License for the specific language governing permissions and
14
+# limitations under the License.
15
+
16
+from charms.reactive import hook
17
+from charms.reactive import RelationBase
18
+from charms.reactive import scopes
19
+
20
+
21
+class db2Requires(RelationBase):
22
+    scope = scopes.GLOBAL
23
+    auto_accessors = ['ssh_key']
24
+
25
+    @hook('{requires:db2}-relation-joined')
26
+    def joined(self):
27
+        self.remove_state('{relation_name}.departed')
28
+        self.set_state('{relation_name}.connected')
29
+
30
+    @hook('{requires:db2}-relation-changed')
31
+    def changed(self):
32
+        self.remove_state('{relation_name}.departed')
33
+        self.set_state('{relation_name}.connected')
34
+        if str(self.get_remote('db2_port')) != "None":
35
+            self.set_state('{relation_name}.ready')
36
+
37
+    @hook('{requires:db2}-relation-departed')
38
+    def departed(self):
39
+        self.remove_state('{relation_name}.connected')
40
+        self.remove_state('{relation_name}.ready')
41
+        self.set_state('{relation_name}.departed')
42
+
43
+    def get_db2_port(self):
44
+        return self.get_remote('db2_port')
45
+
46
+    def get_db2_path(self):
47
+        return self.get_remote('db2_path')
48
+
49
+    def get_db2_hostname(self):
50
+        return self.get_remote('hostname')
51
+
52
+    def get_dbusername(self):
53
+        return self.get_remote('dbusername')
54
+
55
+    def get_dbuserpw(self):
56
+        return self.get_remote('dbuserpw')
57
+
58
+    def get_db2_instance_name(self):
59
+        return self.get_remote('db2_instance_name')
60
+
61
+    def get_db2_dbnames(self):
62
+        return self.get_remote('dbs_created')
63
+
64
+    def set_ssh_keys(self, ssh_key):
65
+        self.set_remote('ssh_key', ssh_key)
66
+
67
+    def set_dbs(self, db_names):
68
+        self.set_remote('db_names', db_names)
Back to file index

hooks/start

 1
--- 
 2
+++ hooks/start
 3
@@ -0,0 +1,19 @@
 4
+#!/usr/bin/env python3
 5
+
 6
+# Load modules from $CHARM_DIR/lib
 7
+import sys
 8
+sys.path.append('lib')
 9
+
10
+from charms.layer import basic
11
+basic.bootstrap_charm_deps()
12
+basic.init_config_states()
13
+
14
+
15
+# This will load and run the appropriate @hook and other decorated
16
+# handlers from $CHARM_DIR/reactive, $CHARM_DIR/hooks/reactive,
17
+# and $CHARM_DIR/hooks/relations.
18
+#
19
+# See https://jujucharms.com/docs/stable/authors-charm-building
20
+# for more information on this pattern.
21
+from charms.reactive import main
22
+main()
Back to file index

hooks/stop

 1
--- 
 2
+++ hooks/stop
 3
@@ -0,0 +1,19 @@
 4
+#!/usr/bin/env python3
 5
+
 6
+# Load modules from $CHARM_DIR/lib
 7
+import sys
 8
+sys.path.append('lib')
 9
+
10
+from charms.layer import basic
11
+basic.bootstrap_charm_deps()
12
+basic.init_config_states()
13
+
14
+
15
+# This will load and run the appropriate @hook and other decorated
16
+# handlers from $CHARM_DIR/reactive, $CHARM_DIR/hooks/reactive,
17
+# and $CHARM_DIR/hooks/relations.
18
+#
19
+# See https://jujucharms.com/docs/stable/authors-charm-building
20
+# for more information on this pattern.
21
+from charms.reactive import main
22
+main()
Back to file index

hooks/update-status

 1
--- 
 2
+++ hooks/update-status
 3
@@ -0,0 +1,19 @@
 4
+#!/usr/bin/env python3
 5
+
 6
+# Load modules from $CHARM_DIR/lib
 7
+import sys
 8
+sys.path.append('lib')
 9
+
10
+from charms.layer import basic
11
+basic.bootstrap_charm_deps()
12
+basic.init_config_states()
13
+
14
+
15
+# This will load and run the appropriate @hook and other decorated
16
+# handlers from $CHARM_DIR/reactive, $CHARM_DIR/hooks/reactive,
17
+# and $CHARM_DIR/hooks/relations.
18
+#
19
+# See https://jujucharms.com/docs/stable/authors-charm-building
20
+# for more information on this pattern.
21
+from charms.reactive import main
22
+main()
Back to file index

hooks/upgrade-charm

 1
--- 
 2
+++ hooks/upgrade-charm
 3
@@ -0,0 +1,28 @@
 4
+#!/usr/bin/env python3
 5
+
 6
+# Load modules from $CHARM_DIR/lib
 7
+import os
 8
+import sys
 9
+sys.path.append('lib')
10
+
11
+# This is an upgrade-charm context, make sure we install latest deps
12
+if not os.path.exists('wheelhouse/.upgrade'):
13
+    open('wheelhouse/.upgrade', 'w').close()
14
+    if os.path.exists('wheelhouse/.bootstrapped'):
15
+        os.unlink('wheelhouse/.bootstrapped')
16
+else:
17
+    os.unlink('wheelhouse/.upgrade')
18
+
19
+from charms.layer import basic
20
+basic.bootstrap_charm_deps()
21
+basic.init_config_states()
22
+
23
+
24
+# This will load and run the appropriate @hook and other decorated
25
+# handlers from $CHARM_DIR/reactive, $CHARM_DIR/hooks/reactive,
26
+# and $CHARM_DIR/hooks/relations.
27
+#
28
+# See https://jujucharms.com/docs/stable/authors-charm-building
29
+# for more information on this pattern.
30
+from charms.reactive import main
31
+main()
Back to file index

icon.svg

 1
--- 
 2
+++ icon.svg
 3
@@ -0,0 +1,29 @@
 4
+<?xml version="1.0" encoding="UTF-8"?>
 5
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
 6
+<!-- Creator: CorelDRAW X6 -->
 7
+<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" width="1in" height="0.999996in" version="1.1" shape-rendering="geometricPrecision" text-rendering="geometricPrecision" image-rendering="optimizeQuality" fill-rule="evenodd" clip-rule="evenodd"
 8
+viewBox="0 0 1000 1000"
 9
+ xmlns:xlink="http://www.w3.org/1999/xlink">
10
+ <defs>
11
+    <linearGradient id="id0" gradientUnits="userSpaceOnUse" x1="500" y1="999.992" x2="500" y2="0">
12
+     <stop offset="0" stop-color="#039935"/>
13
+     <stop offset="1" stop-color="#75E69B"/>
14
+    </linearGradient>
15
+    <mask id="id1">
16
+      <linearGradient id="id2" gradientUnits="userSpaceOnUse" x1="500" y1="58.4803" x2="500" y2="307.016">
17
+       <stop offset="0" stop-opacity="1" stop-color="white"/>
18
+       <stop offset="0.141176" stop-opacity="77.8" stop-color="white"/>
19
+       <stop offset="1" stop-opacity="0" stop-color="white"/>
20
+      </linearGradient>
21
+     <rect fill="url(#id2)" width="1000" height="365"/>
22
+    </mask>
23
+ </defs>
24
+ <g id="Layer_x0020_1">
25
+  <metadata id="CorelCorpID_0Corel-Layer"/>
26
+  <g id="_144357312">
27
+   <path id="Background" fill="url(#id0)" d="M0 676l0 -352c0,-283 41,-324 324,-324l352 0c284,0 324,41 324,324l0 352c0,283 -40,324 -324,324l-352 0c-283,0 -324,-41 -324,-324z"/>
28
+   <path fill="#999999" mask="url(#id1)" d="M0 365l0 -41c0,-283 41,-324 324,-324l352 0c284,0 324,41 324,324l0 41c0,-283 -40,-324 -324,-324l-352 0c-283,0 -324,41 -324,324z"/>
29
+   <path fill="white" fill-rule="nonzero" d="M373 489c0,55 -7,96 -21,121 -16,28 -43,42 -81,42l-106 0 0 -313 104 0c35,0 60,9 75,27 19,22 29,64 29,123zm-66 4c0,-43 -4,-72 -12,-87 -7,-13 -21,-20 -42,-20l-25 0 0 219 25 0c20,0 34,-8 42,-22 8,-16 12,-46 12,-90zm308 70c0,29 -8,51 -24,66 -16,15 -38,23 -66,23l-114 0 0 -313 112 0c24,0 44,6 58,17 17,14 25,34 25,61 0,21 -6,38 -17,50 -10,11 -20,17 -31,19l0 1c12,0 24,5 35,15 15,14 22,35 22,61zm-73 -136c0,-27 -12,-41 -37,-41l-31 0 0 82 31 0c10,0 19,-3 25,-10 8,-7 12,-17 12,-31zm7 131c0,-32 -15,-48 -44,-48l-31 0 0 95 31 0c30,0 44,-16 44,-47zm286 94l-191 0c1,-47 20,-88 57,-124l38 -36c12,-11 20,-20 24,-28 5,-10 8,-23 8,-38 0,-27 -10,-41 -31,-41 -11,0 -19,3 -24,10 -6,10 -10,26 -10,49l-61 0c0,-37 8,-63 25,-79 15,-16 39,-23 72,-23 62,0 93,28 93,86 0,35 -12,63 -35,84l-41 38c-20,18 -34,36 -42,52l118 0 0 50z"/>
30
+  </g>
31
+ </g>
32
+</svg>
Back to file index

layer.yaml

 1
--- 
 2
+++ layer.yaml
 3
@@ -0,0 +1,15 @@
 4
+"options":
 5
+  "basic":
 6
+    "packages":
 7
+    - "binutils"
 8
+    - "pwgen"
 9
+    - "tar"
10
+    - "unzip"
11
+
12
+    "use_venv": !!bool "false"
13
+    "include_system_packages": !!bool "false"
14
+  "ibm-db2-dae": {}
15
+"includes":
16
+- "layer:basic"
17
+- "interface:db2"
18
+"is": "ibm-db2-dae"
Back to file index

lib/charms/layer/__init__.py

 1
--- 
 2
+++ lib/charms/layer/__init__.py
 3
@@ -0,0 +1,21 @@
 4
+import os
 5
+
 6
+
 7
+class LayerOptions(dict):
 8
+    def __init__(self, layer_file, section=None):
 9
+        import yaml  # defer, might not be available until bootstrap
10
+        with open(layer_file) as f:
11
+            layer = yaml.safe_load(f.read())
12
+        opts = layer.get('options', {})
13
+        if section and section in opts:
14
+            super(LayerOptions, self).__init__(opts.get(section))
15
+        else:
16
+            super(LayerOptions, self).__init__(opts)
17
+
18
+
19
+def options(section=None, layer_file=None):
20
+    if not layer_file:
21
+        base_dir = os.environ.get('CHARM_DIR', os.getcwd())
22
+        layer_file = os.path.join(base_dir, 'layer.yaml')
23
+
24
+    return LayerOptions(layer_file, section)
Back to file index

lib/charms/layer/basic.py

  1
--- 
  2
+++ lib/charms/layer/basic.py
  3
@@ -0,0 +1,205 @@
  4
+import os
  5
+import sys
  6
+import shutil
  7
+from glob import glob
  8
+from subprocess import check_call, CalledProcessError
  9
+from time import sleep
 10
+
 11
+from charms.layer.execd import execd_preinstall
 12
+
 13
+
 14
+def lsb_release():
 15
+    """Return /etc/lsb-release in a dict"""
 16
+    d = {}
 17
+    with open('/etc/lsb-release', 'r') as lsb:
 18
+        for l in lsb:
 19
+            k, v = l.split('=')
 20
+            d[k.strip()] = v.strip()
 21
+    return d
 22
+
 23
+
 24
+def bootstrap_charm_deps():
 25
+    """
 26
+    Set up the base charm dependencies so that the reactive system can run.
 27
+    """
 28
+    # execd must happen first, before any attempt to install packages or
 29
+    # access the network, because sites use this hook to do bespoke
 30
+    # configuration and install secrets so the rest of this bootstrap
 31
+    # and the charm itself can actually succeed. This call does nothing
 32
+    # unless the operator has created and populated $CHARM_DIR/exec.d.
 33
+    execd_preinstall()
 34
+    # ensure that $CHARM_DIR/bin is on the path, for helper scripts
 35
+    os.environ['PATH'] += ':%s' % os.path.join(os.environ['CHARM_DIR'], 'bin')
 36
+    venv = os.path.abspath('../.venv')
 37
+    vbin = os.path.join(venv, 'bin')
 38
+    vpip = os.path.join(vbin, 'pip')
 39
+    vpy = os.path.join(vbin, 'python')
 40
+    if os.path.exists('wheelhouse/.bootstrapped'):
 41
+        activate_venv()
 42
+        return
 43
+    # bootstrap wheelhouse
 44
+    if os.path.exists('wheelhouse'):
 45
+        with open('/root/.pydistutils.cfg', 'w') as fp:
 46
+            # make sure that easy_install also only uses the wheelhouse
 47
+            # (see https://github.com/pypa/pip/issues/410)
 48
+            charm_dir = os.environ['CHARM_DIR']
 49
+            fp.writelines([
 50
+                "[easy_install]\n",
 51
+                "allow_hosts = ''\n",
 52
+                "find_links = file://{}/wheelhouse/\n".format(charm_dir),
 53
+            ])
 54
+        apt_install([
 55
+            'python3-pip',
 56
+            'python3-setuptools',
 57
+            'python3-yaml',
 58
+            'python3-dev',
 59
+        ])
 60
+        from charms import layer
 61
+        cfg = layer.options('basic')
 62
+        # include packages defined in layer.yaml
 63
+        apt_install(cfg.get('packages', []))
 64
+        # if we're using a venv, set it up
 65
+        if cfg.get('use_venv'):
 66
+            if not os.path.exists(venv):
 67
+                series = lsb_release()['DISTRIB_CODENAME']
 68
+                if series in ('precise', 'trusty'):
 69
+                    apt_install(['python-virtualenv'])
 70
+                else:
 71
+                    apt_install(['virtualenv'])
 72
+                cmd = ['virtualenv', '-ppython3', '--never-download', venv]
 73
+                if cfg.get('include_system_packages'):
 74
+                    cmd.append('--system-site-packages')
 75
+                check_call(cmd)
 76
+            os.environ['PATH'] = ':'.join([vbin, os.environ['PATH']])
 77
+            pip = vpip
 78
+        else:
 79
+            pip = 'pip3'
 80
+            # save a copy of system pip to prevent `pip3 install -U pip`
 81
+            # from changing it
 82
+            if os.path.exists('/usr/bin/pip'):
 83
+                shutil.copy2('/usr/bin/pip', '/usr/bin/pip.save')
 84
+        # need newer pip, to fix spurious Double Requirement error:
 85
+        # https://github.com/pypa/pip/issues/56
 86
+        check_call([pip, 'install', '-U', '--no-index', '-f', 'wheelhouse',
 87
+                    'pip'])
 88
+        # install the rest of the wheelhouse deps
 89
+        check_call([pip, 'install', '-U', '--no-index', '-f', 'wheelhouse'] +
 90
+                   glob('wheelhouse/*'))
 91
+        if not cfg.get('use_venv'):
 92
+            # restore system pip to prevent `pip3 install -U pip`
 93
+            # from changing it
 94
+            if os.path.exists('/usr/bin/pip.save'):
 95
+                shutil.copy2('/usr/bin/pip.save', '/usr/bin/pip')
 96
+                os.remove('/usr/bin/pip.save')
 97
+        os.remove('/root/.pydistutils.cfg')
 98
+        # flag us as having already bootstrapped so we don't do it again
 99
+        open('wheelhouse/.bootstrapped', 'w').close()
100
+        # Ensure that the newly bootstrapped libs are available.
101
+        # Note: this only seems to be an issue with namespace packages.
102
+        # Non-namespace-package libs (e.g., charmhelpers) are available
103
+        # without having to reload the interpreter. :/
104
+        reload_interpreter(vpy if cfg.get('use_venv') else sys.argv[0])
105
+
106
+
107
+def activate_venv():
108
+    """
109
+    Activate the venv if enabled in ``layer.yaml``.
110
+
111
+    This is handled automatically for normal hooks, but actions might
112
+    need to invoke this manually, using something like:
113
+
114
+        # Load modules from $CHARM_DIR/lib
115
+        import sys
116
+        sys.path.append('lib')
117
+
118
+        from charms.layer.basic import activate_venv
119
+        activate_venv()
120
+
121
+    This will ensure that modules installed in the charm's
122
+    virtual environment are available to the action.
123
+    """
124
+    venv = os.path.abspath('../.venv')
125
+    vbin = os.path.join(venv, 'bin')
126
+    vpy = os.path.join(vbin, 'python')
127
+    from charms import layer
128
+    cfg = layer.options('basic')
129
+    if cfg.get('use_venv') and '.venv' not in sys.executable:
130
+        # activate the venv
131
+        os.environ['PATH'] = ':'.join([vbin, os.environ['PATH']])
132
+        reload_interpreter(vpy)
133
+
134
+
135
+def reload_interpreter(python):
136
+    """
137
+    Reload the python interpreter to ensure that all deps are available.
138
+
139
+    Newly installed modules in namespace packages sometimes seemt to
140
+    not be picked up by Python 3.
141
+    """
142
+    os.execve(python, [python] + list(sys.argv), os.environ)
143
+
144
+
145
+def apt_install(packages):
146
+    """
147
+    Install apt packages.
148
+
149
+    This ensures a consistent set of options that are often missed but
150
+    should really be set.
151
+    """
152
+    if isinstance(packages, (str, bytes)):
153
+        packages = [packages]
154
+
155
+    env = os.environ.copy()
156
+
157
+    if 'DEBIAN_FRONTEND' not in env:
158
+        env['DEBIAN_FRONTEND'] = 'noninteractive'
159
+
160
+    cmd = ['apt-get',
161
+           '--option=Dpkg::Options::=--force-confold',
162
+           '--assume-yes',
163
+           'install']
164
+    for attempt in range(3):
165
+        try:
166
+            check_call(cmd + packages, env=env)
167
+        except CalledProcessError:
168
+            if attempt == 2:  # third attempt
169
+                raise
170
+            sleep(5)
171
+        else:
172
+            break
173
+
174
+
175
+def init_config_states():
176
+    import yaml
177
+    from charmhelpers.core import hookenv
178
+    from charms.reactive import set_state
179
+    from charms.reactive import toggle_state
180
+    config = hookenv.config()
181
+    config_defaults = {}
182
+    config_defs = {}
183
+    config_yaml = os.path.join(hookenv.charm_dir(), 'config.yaml')
184
+    if os.path.exists(config_yaml):
185
+        with open(config_yaml) as fp:
186
+            config_defs = yaml.safe_load(fp).get('options', {})
187
+            config_defaults = {key: value.get('default')
188
+                               for key, value in config_defs.items()}
189
+    for opt in config_defs.keys():
190
+        if config.changed(opt):
191
+            set_state('config.changed')
192
+            set_state('config.changed.{}'.format(opt))
193
+        toggle_state('config.set.{}'.format(opt), config.get(opt))
194
+        toggle_state('config.default.{}'.format(opt),
195
+                     config.get(opt) == config_defaults[opt])
196
+    hookenv.atexit(clear_config_states)
197
+
198
+
199
+def clear_config_states():
200
+    from charmhelpers.core import hookenv, unitdata
201
+    from charms.reactive import remove_state
202
+    config = hookenv.config()
203
+    remove_state('config.changed')
204
+    for opt in config.keys():
205
+        remove_state('config.changed.{}'.format(opt))
206
+        remove_state('config.set.{}'.format(opt))
207
+        remove_state('config.default.{}'.format(opt))
208
+    unitdata.kv().flush()
Back to file index

lib/charms/layer/execd.py

  1
--- 
  2
+++ lib/charms/layer/execd.py
  3
@@ -0,0 +1,138 @@
  4
+# Copyright 2014-2016 Canonical Limited.
  5
+#
  6
+# This file is part of layer-basic, the reactive base layer for Juju.
  7
+#
  8
+# charm-helpers is free software: you can redistribute it and/or modify
  9
+# it under the terms of the GNU Lesser General Public License version 3 as
 10
+# published by the Free Software Foundation.
 11
+#
 12
+# charm-helpers is distributed in the hope that it will be useful,
 13
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
 14
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 15
+# GNU Lesser General Public License for more details.
 16
+#
 17
+# You should have received a copy of the GNU Lesser General Public License
 18
+# along with charm-helpers.  If not, see <http://www.gnu.org/licenses/>.
 19
+
 20
+# This module may only import from the Python standard library.
 21
+import os
 22
+import sys
 23
+import subprocess
 24
+import time
 25
+
 26
+'''
 27
+execd/preinstall
 28
+
 29
+It is often necessary to configure and reconfigure machines
 30
+after provisioning, but before attempting to run the charm.
 31
+Common examples are specialized network configuration, enabling
 32
+of custom hardware, non-standard disk partitioning and filesystems,
 33
+adding secrets and keys required for using a secured network.
 34
+
 35
+The reactive framework's base layer invokes this mechanism as
 36
+early as possible, before any network access is made or dependencies
 37
+unpacked or non-standard modules imported (including the charms.reactive
 38
+framework itself).
 39
+
 40
+Operators needing to use this functionality may branch a charm and
 41
+create an exec.d directory in it. The exec.d directory in turn contains
 42
+one or more subdirectories, each of which contains an executable called
 43
+charm-pre-install and any other required resources. The charm-pre-install
 44
+executables are run, and if successful, state saved so they will not be
 45
+run again.
 46
+
 47
+    $CHARM_DIR/exec.d/mynamespace/charm-pre-install
 48
+
 49
+An alternative to branching a charm is to compose a new charm that contains
 50
+the exec.d directory, using the original charm as a layer,
 51
+
 52
+A charm author could also abuse this mechanism to modify the charm
 53
+environment in unusual ways, but for most purposes it is saner to use
 54
+charmhelpers.core.hookenv.atstart().
 55
+'''
 56
+
 57
+
 58
+def default_execd_dir():
 59
+    return os.path.join(os.environ['CHARM_DIR'], 'exec.d')
 60
+
 61
+
 62
+def execd_module_paths(execd_dir=None):
 63
+    """Generate a list of full paths to modules within execd_dir."""
 64
+    if not execd_dir:
 65
+        execd_dir = default_execd_dir()
 66
+
 67
+    if not os.path.exists(execd_dir):
 68
+        return
 69
+
 70
+    for subpath in os.listdir(execd_dir):
 71
+        module = os.path.join(execd_dir, subpath)
 72
+        if os.path.isdir(module):
 73
+            yield module
 74
+
 75
+
 76
+def execd_submodule_paths(command, execd_dir=None):
 77
+    """Generate a list of full paths to the specified command within exec_dir.
 78
+    """
 79
+    for module_path in execd_module_paths(execd_dir):
 80
+        path = os.path.join(module_path, command)
 81
+        if os.access(path, os.X_OK) and os.path.isfile(path):
 82
+            yield path
 83
+
 84
+
 85
+def execd_sentinel_path(submodule_path):
 86
+    module_path = os.path.dirname(submodule_path)
 87
+    execd_path = os.path.dirname(module_path)
 88
+    module_name = os.path.basename(module_path)
 89
+    submodule_name = os.path.basename(submodule_path)
 90
+    return os.path.join(execd_path,
 91
+                        '.{}_{}.done'.format(module_name, submodule_name))
 92
+
 93
+
 94
+def execd_run(command, execd_dir=None, stop_on_error=True, stderr=None):
 95
+    """Run command for each module within execd_dir which defines it."""
 96
+    if stderr is None:
 97
+        stderr = sys.stdout
 98
+    for submodule_path in execd_submodule_paths(command, execd_dir):
 99
+        # Only run each execd once. We cannot simply run them in the
100
+        # install hook, as potentially storage hooks are run before that.
101
+        # We cannot rely on them being idempotent.
102
+        sentinel = execd_sentinel_path(submodule_path)
103
+        if os.path.exists(sentinel):
104
+            continue
105
+
106
+        try:
107
+            subprocess.check_call([submodule_path], stderr=stderr,
108
+                                  universal_newlines=True)
109
+            with open(sentinel, 'w') as f:
110
+                f.write('{} ran successfully {}\n'.format(submodule_path,
111
+                                                          time.ctime()))
112
+                f.write('Removing this file will cause it to be run again\n')
113
+        except subprocess.CalledProcessError as e:
114
+            # Logs get the details. We can't use juju-log, as the
115
+            # output may be substantial and exceed command line
116
+            # length limits.
117
+            print("ERROR ({}) running {}".format(e.returncode, e.cmd),
118
+                  file=stderr)
119
+            print("STDOUT<<EOM", file=stderr)
120
+            print(e.output, file=stderr)
121
+            print("EOM", file=stderr)
122
+
123
+            # Unit workload status gets a shorter fail message.
124
+            short_path = os.path.relpath(submodule_path)
125
+            block_msg = "Error ({}) running {}".format(e.returncode,
126
+                                                       short_path)
127
+            try:
128
+                subprocess.check_call(['status-set', 'blocked', block_msg],
129
+                                      universal_newlines=True)
130
+                if stop_on_error:
131
+                    sys.exit(0)  # Leave unit in blocked state.
132
+            except Exception:
133
+                pass  # We care about the exec.d/* failure, not status-set.
134
+
135
+            if stop_on_error:
136
+                sys.exit(e.returncode or 1)  # Error state for pre-1.24 Juju
137
+
138
+
139
+def execd_preinstall(execd_dir=None):
140
+    """Run charm-pre-install for each module within execd_dir."""
141
+    execd_run('charm-pre-install', execd_dir=execd_dir)
Back to file index

metadata.yaml

 1
--- 
 2
+++ metadata.yaml
 3
@@ -0,0 +1,31 @@
 4
+"name": "ibm-db2-dae"
 5
+"summary": "IBM DB2 Direct Advanced Edition"
 6
+"maintainer": "IBM Juju Support Team <jujusupp@us.ibm.com>"
 7
+"description": |
 8
+  IBM DB2 Direct Advanced Edition provides a set of new license metrics to facilitate hybrid cloud deployments. The DB2 Direct Editions provide the same DB2 functionality
 9
+  but add ease of purchase and licensing flexibility using a newly introduced simplified license metric, the Virtual Processor Core (VPC) sold as a monthly license charge.
10
+"tags":
11
+- "ibm"
12
+- "db2"
13
+- "database"
14
+- "misc"
15
+- "ibm-z"
16
+"series":
17
+- "xenial"
18
+"provides":
19
+  "db":
20
+    "interface": "db2"
21
+"min-juju-version": "2.0-beta1"
22
+"resources":
23
+  "ibm_db2_dae_installer":
24
+    "type": "file"
25
+    "filename": "ibm_db2_dae_installer.tar.gz"
26
+    "description": "IBM DB2 DAE installer archive"
27
+  "ibm_db2_dae_license":
28
+    "type": "file"
29
+    "filename": "ibm_db2_dae_license.zip"
30
+    "description": "IBM DB2 DAE activation files"
31
+"subordinate": !!bool "false"
32
+"terms":
33
+- "ibmcharmers/ibm-db2-dae/1"
34
+
Back to file index

reactive/ibm-db2-dae.sh

  1
--- 
  2
+++ reactive/ibm-db2-dae.sh
  3
@@ -0,0 +1,819 @@
  4
+#!/bin/bash
  5
+set -e
  6
+
  7
+source charms.reactive.sh
  8
+
  9
+ARCHITECTURE=`uname -m`
 10
+ARCHIVE_DIR=$CHARM_DIR/files/archives
 11
+DB2_ARCHIVE_DIR=`pwd`
 12
+DB2_USER=db2inst1
 13
+DB2_USER_PW=`pwgen -N 1 15`
 14
+DB2_DAS_USER=dasusr1
 15
+DB2_DAS_USER_PW=`pwgen -N 1 15`
 16
+DB2_FENCE_USER=db2fenc1
 17
+DB2_FENCE_USER_PW=`pwgen -N 1 15`
 18
+DB2_INSTALL_PATH=/opt/ibm/db2/V11.1
 19
+AUTH_KEY_FILE=/root/.ssh/authorized_keys
 20
+TEMP_KEY_FILE=key.txt
 21
+
 22
+cfgusername=""
 23
+
 24
+remoteunit=$cfgusername
 25
+cfgpasswd=""
 26
+dbs_created=""
 27
+
 28
+#Get the cfguser name based on the remote unit name
 29
+get_cfgusername()
 30
+{
 31
+	usr="usr"
 32
+	db="db"
 33
+	cfgusername=$1
 34
+	cfgusername=`echo $cfgusername | cut -d"/" -f1`
 35
+	cfgusername=`echo "$cfgusername" | sed -r 's/-//g' | sed -r 's/ibm//g'`
 36
+	cfgusername=`echo "$cfgusername" | awk '{print substr($0,0,5)}'`
 37
+	remoteunit=$cfgusername
 38
+	cfgusername="$cfgusername$usr"
 39
+	remoteunitdbname="$remoteunit$db"
 40
+
 41
+}
 42
+# Check whether DB2 DAE is installed
 43
+is_db2_installed()
 44
+{
 45
+	if [ -d $DB2_INSTALL_PATH/bin ]; then
 46
+		echo "True"
 47
+	else
 48
+		echo "False"
 49
+	fi
 50
+}
 51
+
 52
+
 53
+# Remove DB2 DAE, if installed
 54
+remove_software()
 55
+{
 56
+	db2_inst=`is_db2_installed`
 57
+	if  [ $db2_inst == "True" ]; then
 58
+		juju-log "IBM DB2 DAE: Removing IBM DB2 DAE software."
 59
+		status-set maintenance "Removing IBM DB2 DAE"
 60
+
 61
+		#finding the DB alias names to be dropped and dropping all Databases in that
 62
+		for queue1 in `su - $DB2_USER -c 'db2ilist'`;
 63
+		do
 64
+			juju-log "IBM DB2 DAE: Dropping the Databases for the instance $queue1"
 65
+			#if db2 is not running, we need to start it first, otherwise db2 drop command will fail
 66
+			if su - $queue1 -c 'ps -eaf|grep -i "\bdb2sysc 0\b" |grep -i '$queue1;
 67
+			then
 68
+				juju-log "IBM DB2 DAE: DB2 already started for the user $queue1"
 69
+			else
 70
+				su - $queue1 -c 'db2start'
 71
+				juju-log "IBM DB2 DAE: DB2 is started"
 72
+			fi
 73
+
 74
+			for queue in `su - $queue1 -c 'db2 list db directory | grep "Database alias" | cut -d"=" -f2'`;
 75
+			do
 76
+				queue=`echo $queue | xargs`
 77
+				juju-log "IBM DB2 DAE: Dropping the DB $queue"
 78
+				su - $queue1 -c 'db2 drop database '$queue
 79
+				if [ $? -eq 0 ]; then
 80
+					juju-log "IBM DB2 DAE: Dropped the DB $queue"
 81
+				else
 82
+					juju-log "IBM DB2 DAE: Dropping the DB $queue failed"
 83
+					status-set blocked "Dropping the DB failed"
 84
+					exit 0
 85
+				fi
 86
+			done
 87
+			juju-log "IBM DB2 DAE: Stopping the DB for $queue1"
 88
+
 89
+			if su - $queue1 -c 'ps -eaf|grep -i "\bdb2sysc 0\b" |grep -i '$queue1
 90
+			then
 91
+				su - $queue1 -c 'db2 force application all'
 92
+				su - $queue1 -c 'db2stop'
 93
+				if [ $? -eq 0 ]; then
 94
+					juju-log "IBM DB2 DAE: Stopped the DB for the instance $queue1"
 95
+				else
 96
+					juju-log "IBM DB2 DAE: Stopping the DB for $queue1 failed"
 97
+					status-set blocked "Stopping the DB for $queue1 failed"
 98
+					exit 0
 99
+				fi
100
+
101
+			else
102
+				juju-log "IBM DB2 DAE: DB2 is already stopped"
103
+			fi
104
+		done
105
+
106
+		#drop the das
107
+		cd $DB2_INSTALL_PATH/instance
108
+		juju-log "IBM DB2 DAE: Dropping the DAS"
109
+		./dasdrop
110
+		if [ $? -eq 0 ]; then
111
+			juju-log "IBM DB2 DAE: Dropped the DAS"
112
+		else
113
+			juju-log "IBM DB2 DAE: Dropping the DAS failed"
114
+			status-set blocked "Dropping the DAS failed"
115
+			exit 0
116
+		fi
117
+
118
+		#delete the instances
119
+		su - $DB2_USER -c 'db2ilist'
120
+		for queue1 in `su - $DB2_USER -c 'db2ilist'`;
121
+		do
122
+			juju-log "IBM DB2 DAE: Deleting the instance $queue1"
123
+			$DB2_INSTALL_PATH/instance/db2idrop $queue1
124
+			if [ $? -eq 0 ]; then
125
+				juju-log "IBM DB2 DAE: Deleted  the instance $queue1"
126
+			else
127
+				juju-log "IBM DB2 DAE: Deleting the instance $queue1 failed"
128
+				status-set blocked "Deleting the instance $queue1 failed"
129
+				exit 0
130
+			fi
131
+
132
+		done
133
+
134
+		#Delete the instance entries from /etc/services file
135
+		juju-log "IBM DB2 DAE: Deleting the entries from /etc/services"
136
+		sed -i '/db2c_/d' /etc/services
137
+		if [ $? -eq 0 ]; then
138
+			juju-log "IBM DB2 DAE: Deleted the entries from /etc/services"
139
+		else
140
+			juju-log "IBM DB2 DAE: Deletion of the entries from /etc/services failed"
141
+			status-set blocked "Deletion of the entries from /etc/services failed"
142
+			exit 0
143
+		fi
144
+
145
+		#uninstall
146
+		juju-log "IBM DB2 DAE: Uninstall "
147
+		cd $DB2_INSTALL_PATH/install
148
+		set +e
149
+		./db2_deinstall -a
150
+		if [ $? -eq 0 ]; then
151
+			juju-log "IBM DB2 DAE: Uninstall of db2 successful"
152
+		else
153
+			juju-log "IBM DB2 DAE: Uninstall of db2 failed"
154
+			status-set blocked "IBM DB2 DAE Uninstallation failed"
155
+			exit 0
156
+		fi
157
+		set -e
158
+		cd /opt/ibm
159
+		rm -rf db2
160
+		juju-log "IBM DB2 DAE: Finished Uninstalling......."
161
+		status-set blocked "IBM DB2 DAE Uninstalled"
162
+
163
+	else
164
+		juju-log "IBM DB2 DAE: DB2 not installed"
165
+	fi
166
+
167
+}
168
+
169
+# Update system configuration after installing DB2
170
+configure_system()
171
+{
172
+	juju-log "IBM DB2 DAE: Updating system configuration."
173
+	cd $DB2_INSTALL_PATH/instance
174
+	su - $DB2_USER -c 'db2set DB2COMM=tcpip'
175
+
176
+	#Start DB for the DB2_user
177
+	if su - $DB2_USER -c 'ps -eaf|grep -i "\bdb2sysc 0\b" |grep -i '$DB2_USER;
178
+	then
179
+		juju-log "IBM DB2 DAE: DB2 already started for the user $DB2_USER"
180
+	else
181
+		su - $DB2_USER -c 'db2start'
182
+		juju-log "IBM DB2 DAE: DB2 is started"
183
+	fi
184
+
185
+	service_name=`su - $DB2_USER -c 'db2 get dbm cfg|grep -i svce|cut -d"=" -f2'`
186
+	port_num=`grep $service_name /etc/services | cut -d"/" -f1 | cut -f2`
187
+	port_num=`echo $port_num | xargs`
188
+	if su - $DB2_USER -c 'netstat -an | grep '$port_num;
189
+	then
190
+		juju-log "IBM DB2 DAE: DB2 started on port $port_num"
191
+	else
192
+		juju-log "IBM DB2 DAE: DB2 not started on port $port_num"
193
+		exit 1
194
+	fi
195
+
196
+	juju-log "IBM DB2 DAE: Updated system configuration."
197
+
198
+}
199
+
200
+#Configure dftdbpath
201
+configure_dftdbpath()
202
+{
203
+	db2_inst=`is_db2_installed`
204
+	if  [ $db2_inst == "True" ]; then
205
+		cfgdbpath=`config-get dftdbpath`
206
+		#If null, assign the default value
207
+		if [ "cfgdbpath" == "" ]
208
+		then
209
+			cfgdbpath="/tmp"
210
+		fi
211
+
212
+		for queue1 in `su - $DB2_USER -c 'db2ilist'`;
213
+		do
214
+			#if db2 is not running don't do anything
215
+			if su - $queue1 -c 'ps -eaf|grep -i "\bdb2sysc 0\b" |grep -i '$queue1;
216
+			then
217
+				su - $queue1 -c 'db2 attach to '$queue1
218
+				dbpath=`su - $queue1 -c 'db2 get dbm cfg|grep -i DFTDBPATH|cut -d"=" -f2'`
219
+				cfgdbpath=`echo $cfgdbpath | xargs`
220
+				dbpath=`echo $dbpath | xargs`
221
+				if  [ "$cfgdbpath" != "$dbpath" ]; then
222
+					if [ -d "$cfgdbpath" ]; then
223
+						su - $queue1 -c 'db2 update dbm cfg using DFTDBPATH '$cfgdbpath
224
+						if [ $? -eq 0 ]; then
225
+							juju-log "IBM DB2 DAE: DFTDBPATH changed to $cfgdbpath"
226
+						else
227
+							juju-log "IBM DB2 DAE: Unable to set DFTDBPATH to $cfgdbpath"
228
+							exit 0
229
+						fi
230
+					else
231
+						juju-log "IBM DB2 DAE: Not a valid path. Please check the path and run the command again"
232
+						exit 0
233
+					fi
234
+				fi
235
+			fi
236
+		done
237
+	else
238
+		juju-log "IBM DB2 DAE: DB2 is not installed. Install DB2 to change the dbpath"
239
+		exit 0
240
+	fi
241
+}
242
+
243
+# Edit the response file for UID
244
+edit_responsefile()
245
+{
246
+	rsp_file=db2server_temp.rsp
247
+	orgrsp_file=db2server_z.rsp	
248
+	
249
+	cp $CHARM_DIR/files/archives/$orgrsp_file $CHARM_DIR/files/archives/$rsp_file
250
+          sed -i s/V10.5/V11.1/g  $CHARM_DIR/files/archives/$rsp_file
251
+	db2uid=`id $DB2_USER | cut -d"=" -f2 | cut -d"(" -f1`
252
+	sed -i s/db2inst1_uid/$db2uid/g  $CHARM_DIR/files/archives/$rsp_file
253
+	sed -i s/db2inst1_gid/$db2uid/g  $CHARM_DIR/files/archives/$rsp_file
254
+	sed -i s/db2inst1_homedir/$DB2_USER/g $CHARM_DIR/files/archives/$rsp_file
255
+	sed -i s/db2inst1_password/$DB2_USER_PW/g $CHARM_DIR/files/archives/$rsp_file
256
+
257
+	db2fenid=`id $DB2_FENCE_USER | cut -d"=" -f2 | cut -d"(" -f1`
258
+	sed -i s/db2fenc1_uid/$db2fenid/g  $CHARM_DIR/files/archives/$rsp_file
259
+	sed -i s/db2fenc1_gid/$db2fenid/g  $CHARM_DIR/files/archives/$rsp_file
260
+
261
+	dasuid=`id $DB2_DAS_USER | cut -d"=" -f2 | cut -d"(" -f1`
262
+	sed -i s/das_uid/$dasuid/g $CHARM_DIR/files/archives/$rsp_file
263
+	sed -i s/das_gid/$dasuid/g $CHARM_DIR/files/archives/$rsp_file
264
+
265
+}
266
+
267
+create_user()
268
+{
269
+	servicename=$1
270
+	user_exists=0
271
+	instance_exists=0
272
+	db2_inst=`is_db2_installed`
273
+	get_cfgusername $servicename
274
+	if  [ $db2_inst == "True" ]; then
275
+		status-set maintenance "Creating DB user and instance"
276
+		#Find the group id for db2inst1 user which is used to install db2 and find all
277
+		#users belonging to this user
278
+		db2inst1grpid=`id $DB2_USER |  cut -d" " -f2`
279
+
280
+		#If the user is already available, just log the information.
281
+		for queue2 in `awk -F':' '{ print $1}' /etc/passwd`;
282
+		do
283
+			gid=`id $queue2 |  cut -d" " -f2`
284
+			if [ $gid == $db2inst1grpid ]; then
285
+				if [ $queue2 != "$DB2_USER" ]; then
286
+					if [ $cfgusername == $queue2  ]; then
287
+						juju-log "IBM DB2 DAE: User $cfgusername already exists"
288
+						user_exists=1
289
+					fi
290
+				fi
291
+			fi
292
+		done
293
+		
294
+
295
+		#If not available, add a new user
296
+		if [ $user_exists -ne 1 ]; then
297
+			juju-log "IBM DB2 DAE: Creating New user"
298
+			create_newuser $servicename
299
+			juju-log "IBM DB2 DAE: Created New user"
300
+			juju-log $cfgusername
301
+		fi
302
+
303
+ 		#Set the password if there is no password available in the interface.
304
+		existingpw=$(relation_call --state=db.ready get_db_password $service) || true
305
+		juju-log "IBM DB2 DAE: Exisitng password is $existingpw"
306
+		if [ "$existingpw" == "None" ]; then
307
+		#Create a password
308
+			passwd=`pwgen -N 1 15`
309
+			cfgpasswd="$cfgusername$passwd"
310
+
311
+			#Set the password for the new user
312
+			juju-log "IBM DB2 DAE: Setting the password in new user"
313
+			echo $cfgusername:$cfgpasswd | chpasswd
314
+			if [ $? -ne 0 ]; then
315
+				juju-log "IBM DB2 DAE: Setting password for user $cfgusername failed."
316
+				status-set blocked "Setting the password for user failed, Try again"
317
+				exit 0
318
+			fi
319
+
320
+			#Send the password to the interface
321
+			juju-log "IBM DB2 DAE: Setting password to interface $cfgpasswd"
322
+			relation_call --state=db.ready set_db_password $service $cfgpasswd || true
323
+			password_interface=$(relation_call --state=db.ready get_db_password $servicename) || true
324
+			juju-log "IBM DB2 DAE: Getting password from interfce $password_interface"
325
+		fi
326
+
327
+		#Creating a new instance for the new user if not existing
328
+		for queue1 in `su - $DB2_USER -c 'db2ilist'`;
329
+		do
330
+			if [ $queue1 == $cfgusername ]; then
331
+				juju-log "IBM DB2 DAE: Instance $cfgusername already exists"
332
+				instance_exists=1
333
+			fi
334
+		done
335
+		if [ $instance_exists -ne 1 ]; then
336
+			juju-log "IBM DB2 DAE: Creating new instance for the user"
337
+			$DB2_INSTALL_PATH/instance/db2icrt -u $cfgusername $cfgusername
338
+			if [ $? = 0 ]; then
339
+				juju-log "IBM DB2 DAE: Created new instance for the user"
340
+			else
341
+				juju-log "IBM DB2 DAE: Creation of new instance failed"
342
+				exit 0
343
+			fi
344
+		fi
345
+
346
+		#Do the configuration for the new instance created
347
+		new_port=50001
348
+		free_port=0
349
+		is_free=0
350
+		#Check whether the port number is already in etc/services file, and then add it
351
+		cd /etc
352
+		if grep -q "db2c_$cfgusername" services
353
+		then
354
+			juju-log "IBM DB2 DAE: Services file already updated"
355
+		else
356
+			while [ $free_port -eq 0 ]
357
+			do
358
+				is_free=`netstat -lnp | grep $new_port | cut -d":" -f2 | cut -d" " -f1`
359
+				if [ "$is_free" != "$new_port" ]; then
360
+					free_port=1
361
+				else
362
+					new_port=$((new_port+1))
363
+				fi
364
+			done
365
+			juju-log "IBM DB2 DAE:Updating Services file"
366
+			echo -e "db2c_$cfgusername	$new_port/tcp" >> /etc/services
367
+			su - $cfgusername -c 'set db2instance=$cfgusername'
368
+			su - $cfgusername -c 'db2set DB2COMM=tcpip'
369
+			new_port=`echo $new_port | xargs`
370
+				#port_num_consumer=$new_port
371
+			su - $cfgusername -c 'db2 update dbm cfg using svcename '$new_port
372
+			$DB2_INSTALL_PATH/instance/db2iupdt $cfgusername
373
+		fi
374
+		cd -
375
+
376
+		#Start DB for the new user
377
+		if su - $cfgusername -c 'ps -eaf|grep -i "\bdb2sysc 0\b" |grep -i '$cfgusername;
378
+		then
379
+			juju-log "IBM DB2 DAE: DB2 already started for the user $cfgusername"
380
+		else
381
+			su - $cfgusername -c 'db2start'
382
+			juju-log "IBM DB2 DAE: DB2 is started"
383
+		fi
384
+		#set_state 'db.dbstarted'
385
+
386
+	else
387
+		juju-log "IBM DB2 DAE: DB2 DAE is not installed. Install DB2 DAE before creating users"
388
+		exit 0
389
+
390
+	fi
391
+	status-set active "Completed DB user and instance creation"
392
+}
393
+
394
+create_newuser()
395
+{
396
+	servicename=$1
397
+	dbcreated="False"
398
+	#Add the new user
399
+	get_cfgusername $servicename
400
+	useradd -g db2grp1 -G dasadm1 -m $cfgusername
401
+	if [ $? -ne 0 ]; then
402
+		juju-log "IBM DB2 DAE: Addition of user $queue2 failed."
403
+		status-set blocked "Addition of new used failed, Try again"
404
+		exit 0
405
+	fi
406
+
407
+	#Check whether test DB already exists. If not create it
408
+
409
+	dbname=`su - $DB2_USER -c 'db2 list db directory' | grep "Database name" | grep -i "\bTEST\b" | cut -d"=" -f2`
410
+	dbname=`echo $dbname | xargs`
411
+	if [ "$dbname" != "TEST" ]; then
412
+		juju-log "IBM DB2 DAE: Creating DB Test"
413
+		su - $DB2_USER -c 'db2 create database test'
414
+		if [ $? -ne 0 ]; then
415
+			juju-log "IBM DB2 DAE: DB creation failed"
416
+			status-set blocked "DB creation failed, Try again"
417
+			exit 0
418
+		fi
419
+		juju-log "IBM DB2 DAE: Created DB Test"
420
+	fi
421
+	#Connect to the DB and grant data access
422
+	su - $DB2_USER -c 'db2 connect to test;db2 grant dataaccess on database to user '$cfgusername
423
+	if [ $? -ne 0 ]; then
424
+		juju-log "IBM DB2 DAE: Grant access failed"
425
+		status-set blocked "Grant dataaccess on database failed, Try again"
426
+		exit 0
427
+	fi
428
+	su - $DB2_USER -c 'db2 connect to test;db2 disconnect test'
429
+	if [ $? -ne 0 ]; then
430
+		juju-log "IBM DB2 DAE: Disconnect DB failed"
431
+		status-set blocked "Disconnect DB failed"
432
+		exit 0
433
+	fi
434
+
435
+}
436
+
437
+create_database()
438
+{
439
+	setpassword=0
440
+	dbtocreate=$1
441
+	servicename=$2
442
+
443
+	get_cfgusername $servicename
444
+	#create the db for $dbnametocreate if it doesn't exist
445
+	dbname=`su - $cfgusername -c 'db2 list db directory' | grep "Database name" | grep -i "\b$dbtocreate\b" | cut -d"=" -f2`
446
+	dbname=`echo $dbname | xargs`
447
+	dbname=`echo "$dbname" | awk '{ print tolower($1) }'`
448
+	dbtocreate=`echo "$dbtocreate" | awk '{ print tolower($1) }'`
449
+	#check whether dbname is more than 8 chars
450
+	if [ ${#dbtocreate} -gt 8 ]; then
451
+		juju-log "IBM DB2 DAE: Failed to create DB $dbtocreate. DB name should be <= 8 chars"
452
+		exit 0 
453
+		
454
+	else
455
+		if [ "$dbname" != "$dbtocreate" ]; then
456
+			juju-log "IBM DB2 DAE: Creating DB $dbtocreate"
457
+			su - $cfgusername -c 'db2 create database '$dbtocreate
458
+			if [ $? -ne 0 ]; then
459
+				juju-log "IBM DB2 DAE: DB creation failed"
460
+				status-set blocked "DB creation failed, Try again"
461
+				exit 0
462
+			fi
463
+			juju-log "IBM DB2 DAE: Created DB $dbtocreate"
464
+
465
+		else
466
+			juju-log "IBM DB2 DAE: DB $dbtocreate already exists"
467
+		fi
468
+
469
+	fi
470
+}
471
+
472
+# Must be called from a 'db.ready' state handler
473
+create_dbs()
474
+{
475
+dbs_created=""
476
+servicename=$1
477
+dbnames=$(relation_call --state=db.ready get_dbnames $servicename) || true
478
+
479
+#If dbnames is null, create a default DB as per service name. Else create the DBs requested by the related charm
480
+if [ -z "$dbnames" -o "$dbnames" == "None" ] ; then
481
+	juju-log "IBM DB2 DAE: Creating a default DB $remoteunitdbname based on remote service name"
482
+	create_database $remoteunitdbname $servicename
483
+	dbs_created+=$remoteunitdbname
484
+	dbs_created+="."
485
+else
486
+	juju-log "IBM DB2 DAE: Creating the DB names as passed by consumer"
487
+	if [ `echo $dbnames | grep -c "," ` -gt 0 ]
488
+	then
489
+		#parse the $dbnames string to get the names of dbs to be created
490
+		count=1
491
+		db_to_create="test"
492
+		while [ "$db_to_create" != "" ]
493
+		do
494
+			db_to_create=`echo $dbnames | cut -d"," -f$count`
495
+			juju-log "IBM DB2 DAE:db_to_create is $db_to_create"
496
+			if [ "$db_to_create" != "" ] ; then
497
+				create_database $db_to_create $servicename
498
+				juju-log "Created DB $db_to_create"
499
+				dbs_created+=$db_to_create
500
+				dbs_created+="."
501
+			fi
502
+			((count=count+1))
503
+		done
504
+	else
505
+		create_database $dbnames $servicename
506
+		juju-log "Created DB $dbnames"
507
+		dbs_created+=$dbnames
508
+		dbs_created+="."
509
+	fi
510
+fi
511
+}
512
+
513
+remove_sshkeys()
514
+{
515
+	servicename=$1
516
+	#Read the key from the key.txt file and see whether it exists
517
+	if grep -q "$servicename" $TEMP_KEY_FILE
518
+	then
519
+	key=`cat $TEMP_KEY_FILE | grep $servicename | cut -d":" -f2`
520
+	grep -v "$key" $AUTH_KEY_FILE > tempfile.txt || touch tempfile.txt
521
+	mv tempfile.txt $AUTH_KEY_FILE
522
+	if grep -q "$key" $AUTH_KEY_FILE
523
+	then
524
+		juju-log "IBM DB2 DAE: SSH Key not deleted from $AUTH_KEY_FILE"
525
+	else
526
+		juju-log "IBM DB2 DAE: SSH Key deleted from $AUTH_KEY_FILE"
527
+	fi
528
+	#Remove from the temporary file as well
529
+	grep -v "$servicename:$key" $TEMP_KEY_FILE > tempfile1.txt
530
+	mv tempfile1.txt $TEMP_KEY_FILE
531
+	if grep -q "$key" $TEMP_KEY_FILE
532
+	then
533
+		juju-log "IBM DB2 DAE: SSH Key not deleted from $TEMP_KEY_FILE"
534
+	else
535
+		juju-log "IBM DB2 DAE: SSH Key deleted from $TEMP_KEY_FILE"
536
+	fi
537
+
538
+fi
539
+
540
+}
541
+
542
+
543
+@when 'db.connected'
544
+@when_not 'ibm-db2.installed'
545
+function reset_interface_states(){
546
+	services=$(relation_call --state=db.connected services) || true
547
+	for service in $services; do
548
+		juju-log "IBM DB2 DAE: Resetting states for the service $service"
549
+		relation_call --state=db.connected dismiss_sshconfigured $service || true
550
+		relation_call --state=db.connected reset_states $service || true
551
+	done
552
+
553
+}
554
+
555
+
556
+@when_not 'ibm-db2.prereqsinstalled'
557
+function init() {
558
+	if [ "$ARCHITECTURE" != "s390x" ]; then
559
+		juju-log "IBM DB2 DAE: Unsupported platform. IBM DB2 DAE installed with this Charm supports only s390x platform."
560
+		exit 1
561
+	fi
562
+	set -e
563
+	juju-log "IBM DB2 DAE: Begin Install."
564
+	status-set maintenance "Installing pre requisites for IBM DB2 DAE"
565
+	apt-get update
566
+
567
+	juju-log "IBM DB2 DAE: Installing 32 bit libstdc++.so.6"
568
+	apt-get install lib32stdc++6 -y
569
+	juju-log "IBM DB2 DAE: Installed 32 bit libstdc++.so.6"
570
+	juju-log "IBM DB2 DAE: Installing libaio1 and binutils "
571
+	apt-get install libaio1 
572
+	juju-log "IBM DB2 DAE: Installed libaio1 and binutils"
573
+	
574
+	juju-log "IBM DB2 DAE: Creating the user ids for DB2 DAE installation"
575
+	groupadd db2grp1
576
+	groupadd dasadm1
577
+	groupadd db2fgrp1
578
+
579
+	useradd -g db2grp1 -G dasadm1 -m $DB2_USER
580
+	echo $DB2_USER:$DB2_USER_PW | chpasswd
581
+        echo $DB2_USER_PW
582
+	useradd -g dasadm1 -G db2grp1 -m $DB2_DAS_USER
583
+	echo $DB2_DAS_USER:$DB2_DAS_USER_PW | chpasswd
584
+	useradd -g db2fgrp1 -m $DB2_FENCE_USER
585
+	echo $DB2_FENCE_USER:$DB2_FENCE_USER_PW | chpasswd
586
+
587
+	juju-log "IBM DB2 DAE: Created the user ids for db2-dae installation"
588
+	status-set maintenance "Installed pre requisites for IBM DB2 DAE"
589
+	set_state 'ibm-db2.prereqsinstalled'
590
+
591
+}
592
+
593
+@when 'ibm-db2.prereqsinstalled'
594
+@when_not 'ibm-db2.installed'
595
+function install() {
596
+	# Get the installable db2 resources
597
+	juju-log "IBM DB2 DAE: fetching the ibm_db2_dae_installer resource"
598
+	status-set maintenance "IBM DB2 DAE: fetching the ibm_db2_dae_installer resource"
599
+	db2_pkg_name=`resource-get 'ibm_db2_dae_installer' || echo unavailable`
600
+	ibm_db2_installer_isempty=`file $db2_pkg_name | { grep -q empty && echo "True"; } || echo "False"`
601
+	juju-log "IBM DB2 DAE: fetching the ibm_db2_dae_license resource"
602
+        status-set maintenance "IBM DB2 DAE: fetching the ibm_db2_dae_license resource"
603
+        db2_lic_name=`resource-get 'ibm_db2_dae_license' || echo unavailable`
604
+        ibm_db2_lic_isempty=`file $db2_lic_name | { grep -q empty && echo "True"; } || echo "False"`
605
+	# If we don't have a package, report blocked status; we can't proceed.
606
+ 
607
+	if [ "$db2_pkg_name" = "unavailable" -o  "$db2_lic_name" = "unavailable" ]; then
608
+		juju-log "IBM DB2 DAE: Either required IBM DB2 installer is missing or the License Files"
609
+		status-set blocked "missing required ibm_db2_dae_installer/license resource"
610
+		return 0
611
+	fi
612
+	if [ "$ibm_db2_installer_isempty" = "True" -o "$ibm_db2_lic_isempty" = "True" ]; then
613
+		juju-log "IBM DB2 DAE: found empty packages or empty license files."
614
+		status-set blocked "empty ibm_db2_dae_installer/license resource."
615
+		return 0
616
+	fi
617
+        
618
+        
619
+	ARCHIVE_DIR1=`dirname $db2_pkg_name`
620
+	echo "$ARCHIVE_DIR1"
621
+	db2_inst=`is_db2_installed`
622
+	if [[ ! -d $ARCHIVE_DIR1 ]]; then
623
+		mkdir $ARCHIVE_DIR1
624
+	fi
625
+        ARCHIVE_DIR2=`dirname $db2_lic_name`
626
+        echo "$ARCHIVE_DIR2"
627
+	#Install if download succeeded
628
+	if  [ $db2_inst == "False" ]; then
629
+		if [ -f  $ARCHIVE_DIR1/*.gz ] && [ -f  $ARCHIVE_DIR2/*.zip ]; then
630
+
631
+			cd $CHARM_DIR/files/archives
632
+			tar -zxvf $ARCHIVE_DIR1/*.gz
633
+			if [ $? -ne 0 ]; then
634
+				juju-log "IBM DB2 DAE: Unable to extract the DB2 DAE package content. Verify whether the package is corrupt."
635
+				status-set maintenance "Unable to extract the DB2 DAE package content"
636
+				#Remove corrupt archive file
637
+				rm -rf $ARCHIVE_DIR1/*.gz
638
+				exit 0
639
+			fi
640
+			rsp_file=db2server.rsp
641
+			edit_responsefile
642
+			cd $CHARM_DIR/files/archives/server*
643
+			juju-log "IBM DB2 DAE: Edited the response file"
644
+
645
+			juju-log "IBM DB2 DAE: Checking etc/hosts file."
646
+			private_address=`unit-get private-address`
647
+			if grep -q "$private_address" /etc/hosts; then
648
+				juju-log "IBM DB2 DAE: Host file already updated"
649
+			else
650
+				juju-log "IBM DB2 DAE: Updating Host file"
651
+				echo "$private_address `hostname`" >> /etc/hosts
652
+			fi
653
+
654
+			juju-log "IBM DB2 DAE: Installing db2 package."
655
+			status-set maintenance "Installing IBM DB2 DAE"
656
+			set +e
657
+			./db2setup -r $CHARM_DIR/files/archives/$rsp_file
658
+			juju-log "IBM DB2 DAE: Installation of db2 complete."
659
+			set -e
660
+		
661
+			# Activate the license key for enabling the IBM DB2 Direct Advanced Edition.
662
+			cd $CHARM_DIR/files/archives
663
+                       	unzip $ARCHIVE_DIR2/*.zip
664
+                      	if [ $? -ne 0 ]; then
665
+                                juju-log "IBM DB2 DAE: Unable to extract the DB2 DAE license files."
666
+                                status-set maintenance "Unable to extract the DB2 DAE License Files content"
667
+                                #Remove corrupt archive file
668
+                                rm -rf $ARCHIVE_DIR2/*.zip
669
+                                exit 0
670
+                        fi
671
+			cd $DB2_INSTALL_PATH/adm
672
+			./db2licm -a $CHARM_DIR/files/archives/dae_vpc/db2/license/db2dae_vpc.lic
673
+			if [ $? -eq 0 ]; then
674
+				juju-log "IBM DB2 DAE: License Key was applied succcessfully."
675
+			else
676
+				juju-log "IBM DB2 DAE: License Key was not applied successfully, check the logs."
677
+				status-set blocked "IBM DB2 DAE License Key activation failed"
678
+				exit 0
679
+			fi
680
+
681
+		fi
682
+
683
+	fi
684
+			# Configure system values  for Db2
685
+			configure_system
686
+			#Configure DFTDBPATH
687
+			configure_dftdbpath
688
+			echo "Tempory Key File" > $TEMP_KEY_FILE
689
+			set_state 'ibm-db2.installed'
690
+			status-set active "IBM DB2 DAE Installed"
691
+}
692
+
693
+@when 'config.changed.dftdbpath'
694
+function configurevalues(){
695
+	configure_dftdbpath
696
+}
697
+
698
+@when 'ibm-db2.installed'
699
+@when_not 'db.connected'
700
+function report_waiting_on_consumers(){
701
+	status-set active "IBM DB2 DAE Ready (waiting for consumers)"
702
+}
703
+
704
+@when 'ibm-db2.installed'
705
+@when 'db.connected'
706
+function configure_sshkeys(){
707
+	services=$(relation_call --state=db.connected services)
708
+	for service in $services; do
709
+		key=$(relation_call --state=db.connected get_sshkeys $service) || true
710
+		juju-log "IBM DB2 DAE: Received the ssh key $key from the service $service"
711
+
712
+		if [ "$key" == "None" ]; then
713
+			juju-log "IBM DB2 DAE: No data sent yet"
714
+			continue
715
+		fi
716
+
717
+		# Add the key to the authorized_keys file, if it exists
718
+		set +e
719
+		#Create a temp key file if it doesn't exist
720
+		if [ -f $TEMP_KEY_FILE ]; then
721
+			juju-log "IBM DB2 DAE: Temp file already exists"
722
+		else
723
+			echo "Temp Key File" > $TEMP_KEY_FILE
724
+		fi
725
+		if [ -f $AUTH_KEY_FILE ]; then
726
+			# Append only if the key is not present
727
+			juju-log "IBM DB2 DAE: Updating the key file"
728
+			grep "$key" $AUTH_KEY_FILE > /dev/null
729
+			if [ $? -ne 0 ]; then
730
+				juju-log "IBM DB2 DAE: Updating authorized keys file"
731
+				echo "$key" >> $AUTH_KEY_FILE
732
+				echo "$service:$key" >> $TEMP_KEY_FILE
733
+			else
734
+				juju-log "IBM DB2 DAE: Key already present"
735
+			fi
736
+		else
737
+			juju-log "IBM DB2 DAE: Creating authorized keys file"
738
+			echo "$key" > $AUTH_KEY_FILE
739
+			echo "$service:$key" > $TEMP_KEY_FILE
740
+		fi
741
+		relation_call --state=db.connected set_sshconfigured $service || true
742
+		juju-log "IBM DB2 DAE: Completed updating the authorized key"
743
+		set -e
744
+	done
745
+}
746
+
747
+@when 'ibm-db2.installed'
748
+@when 'db.ready'
749
+@when 'db.sshconfigured'
750
+function create_consumer_dbs(){
751
+	services=$(relation_call --state=db.ready services)
752
+	for service in $services; do
753
+
754
+		key=$(relation_call --state=db.ready get_sshkeys $service) || true
755
+                juju-log "IBM DB2 DAE: In create_consumer_dbs function, Received the ssh key $key from the service $service"
756
+
757
+                if [ "$key" == "None" ]; then
758
+                        juju-log "IBM DB2 DAE: No data sent yet"
759
+                        continue
760
+                fi
761
+
762
+
763
+		#Create the user for the remote unit connected
764
+		juju-log "IBM DB2 DAE: Creating the users for the consumer $service"
765
+		create_user $service
766
+		juju-log "IBM DB2 DAE: Create users completed"
767
+
768
+		#Create the DBs after parsing
769
+		juju-log "IBM DB2 DAE: Creating DBs for the consumer $service"
770
+		create_dbs $service
771
+		juju-log "IBM DB2 DAE: Create DBs completed"
772
+
773
+		# If we created a new db, send relation data. Otherwise, the db already
774
+		# existed, so there is no need to send the data.
775
+		get_cfgusername $service
776
+		service_name=`su - $cfgusername -c 'db2 get dbm cfg|grep -i svce|cut -d"=" -f2'`
777
+		db2_port=`grep $service_name /etc/services | cut -d"/" -f1 | grep "db2c_$cfgusername" | cut -f2`
778
+		db2_path="/opt/ibm/db2"
779
+		hostname=`unit-get private-address`
780
+		dbusername=$cfgusername
781
+		db2_instance_name=$cfgusername
782
+		
783
+		dbuserpw=$(relation_call --state=db.ready get_db_password $servicename) || true
784
+		juju-log "IBM DB2 DAE: Getting password from interfceand setting it back $dbuserpw"
785
+
786
+		juju-log "IBM DB2 DAE: Sending the DB details to the consumer $service"
787
+		juju-log "Port number: $db2_port"
788
+		juju-log "Hostname: $hostname"
789
+		juju-log "DBusername: $dbusername DBuserpw: $dbuserpw"
790
+		juju-log "DB Instance name: $db2_instance_name"
791
+		juju-log "Service: $service_name"
792
+		juju-log "DBname: $dbs_created"
793
+
794
+		relation_call --state=db.ready set_db_details $service $db2_path $db2_port $hostname $dbusername $dbuserpw $db2_instance_name $dbs_created || true
795
+		status-set active "IBM DB2 DAE Ready"
796
+	done
797
+}
798
+
799
+@when 'ibm-db2.installed'
800
+@when 'db.departed'
801
+function stop_db2(){
802
+	juju-log "IBM DB2 DAE: Stopping the DB when relation is broken"
803
+	services=$(relation_call --state=db.departed services) || true
804
+	for service in $services; do
805
+		juju-log "IBM DB2 DAE: Service name is $service"
806
+		get_cfgusername $service
807
+		if su - $cfgusername -c 'ps -eaf|grep -i "\bdb2sysc 0\b" |grep -i '$cfgusername
808
+		then
809
+			su - $cfgusername -c 'db2 force applications all'
810
+			su - $cfgusername -c 'db2stop'
811
+			juju-log "IBM DB2 DAE: DB2 DAE stopped for instance $cfgusername"
812
+		else
813
+			juju-log "IBM DB2 DAE: DB2 DAE is already stopped for the instance $cfgusername"
814
+		fi
815
+		#Remove the ssh key entry from ssh keys file
816
+		remove_sshkeys $service
817
+		relation_call --state=db.departed dismiss_sshconfigured $service || true
818
+		relation_call --state=db.departed dismiss $service || true
819
+	done
820
+}
821
+
822
+reactive_handler_main
Back to file index

requirements.txt

1
--- 
2
+++ requirements.txt
3
@@ -0,0 +1,2 @@
4
+flake8
5
+pytest
Back to file index

revision

1
--- 
2
+++ revision
3
@@ -0,0 +1 @@
4
+0
Back to file index

tests/01-deploy.py

 1
--- 
 2
+++ tests/01-deploy.py
 3
@@ -0,0 +1,45 @@
 4
+#!/usr/bin/env python3
 5
+
 6
+import unittest
 7
+import amulet
 8
+
 9
+seconds_to_wait = 20000
10
+
11
+
12
+class TestDeploy(unittest.TestCase):
13
+    """
14
+    Deployment test for the IBM DB2-DAE charm.
15
+    """
16
+    def setUp(self):
17
+        self.d = amulet.Deployment(series='xenial')
18
+        self.d.add('ibm-db2-dae', 'cs:~ibmcharmers/ibm-db2-dae')
19
+        self.d.setup(timeout=900)
20
+        self.d.sentry.wait(timeout=1800)
21
+
22
+    def test_deployed(self):
23
+        """ Test to see if the charm deployed successfully. """
24
+        self.assertTrue(self.d.deployed)
25
+        db2_unit = self.d.sentry['ibm-db2'][0]
26
+        # Get the port num where db2 is running and check for netstat
27
+        output, code = db2_unit.run("su - db2inst1 -c 'db2 get dbm cfg' | grep -i svce | \
28
+                                    cut -d'=' -f2")
29
+        if code != 0:
30
+            message = 'Unable to get the port number where DB2 is running. \
31
+                       Exiting before completing rest of the verification \
32
+                       tests.'
33
+            amulet.raise_status(amulet.FAIL, msg=message)
34
+        print('DB2 DAE running in port num : %s' % output)
35
+        print('Checking netstat command')
36
+        cmd = ("su - db2inst1 -c 'netstat -an' | grep LISTEN | \
37
+               grep %s" % output)
38
+        output, code = db2_unit.run(cmd)
39
+        if code != 0:
40
+            message = 'Unable to get the port number where DB2 is running. \
41
+                       Exiting before completing rest of the verification \
42
+                       tests.'
43
+            amulet.raise_status(amulet.FAIL, msg=message)
44
+        print('Output of netstat command id %s' % output)
45
+
46
+
47
+if __name__ == '__main__':
48
+    unittest.main()
Back to file index

tests/tests.yaml

1
--- 
2
+++ tests/tests.yaml
3
@@ -0,0 +1,5 @@
4
+packages:
5
+  - amulet
6
+  - python3
7
+  - tar
8
+  - unzip
Back to file index

tox.ini

 1
--- 
 2
+++ tox.ini
 3
@@ -0,0 +1,12 @@
 4
+[tox]
 5
+skipsdist=True
 6
+envlist = py34, py35
 7
+skip_missing_interpreters = True
 8
+
 9
+[testenv]
10
+commands = py.test -v
11
+deps =
12
+    -r{toxinidir}/requirements.txt
13
+
14
+[flake8]
15
+exclude=docs