Archive for the ‘Fedora’ Category
Django on Fedora 30
It seemed opportune to add Django to the Fedora 30 instance that I build and maintain for my students. Here are the instructions, which I developed with the prior Fedora 28/29 instructions.
- Check your Python3 installation with the following command:
python3 -V
It should return this but if it doesn’t you should install
python3
:Python 3.7.4
- Check whether
pip3
is installation by installing it when its not:sudo def -y install python3-php
It should return:
Last metadata expiration check: 0:44:52 ago on Tue 10 Sep 2019 11:02:33 AM MDT. Package python3-pip-19.0.3-3.fc30.noarch is already installed. Dependencies resolved. Nothing to do. Complete!
- Check whether
Django
is installation by installing it when its not withpip3
installation utility:sudo pip3 install --user Django
It should return the following if installed:
Requirement already satisfied: Django in /usr/lib/python3.7/site-packages (2.1.10) Requirement already satisfied: pytz in /usr/lib/python3.7/site-packages (from Django) (2018.5)
- Check your
django-admin
account location with thewhich
utility:which django-admin
It should return the following on Fedora 30 when installed:
/usr/bin/django-admin
- Create a Django test application with the
django-admin
utility by creating a project directory. My directory is a bit deep. For reference, it is:/home/student/Code/python/django/projects
Change to that projects directory, and run the following command:
django-admin startproject test_app
After that command change directory with the
cd
command into thetest_app
subdirectory in yourprojects
directory. Run the manage.py program with the following command:python3 manage.py migrate
You should see the following:
Operations to perform: Apply all migrations: admin, auth, contenttypes, sessions Running migrations: Applying contenttypes.0001_initial... OK Applying auth.0001_initial... OK Applying admin.0001_initial... OK Applying admin.0002_logentry_remove_auto_add... OK Applying admin.0003_logentry_add_action_flag_choices... OK Applying contenttypes.0002_remove_content_type_name... OK Applying auth.0002_alter_permission_name_max_length... OK Applying auth.0003_alter_user_email_max_length... OK Applying auth.0004_alter_user_username_opts... OK Applying auth.0005_alter_user_last_login_null... OK Applying auth.0006_require_contenttypes_0002... OK Applying auth.0007_alter_validators_add_error_messages... OK Applying auth.0008_alter_user_username_max_length... OK Applying auth.0009_alter_user_last_name_max_length... OK Applying sessions.0001_initial... OK
Next, your would create an admin
account. You’re done.
Python MySQL Query
Somebody asked me how to expand a prior example with the static variables so that it took arguments at the command line for the variables. This example uses Python 3 new features in the datetime
package.
There’s a small trick converting the string
arguments to date
data types. Here’s a quick example that shows you how to convert the argument list into individual date
data type variables:
#!/usr/bin/python3 # include standard modules import sys from datetime import datetime # Capture argument list. fullCmdArguments = sys.argv # Assignable variables. beginDate = "" endDate = "" # Assign argument list to variable. argumentList = fullCmdArguments[1:] # Enumerate through the argument list where beginDate precedes endDate as strings. try: for i, s in enumerate(argumentList): if (i == 0): beginDate = datetime.date(datetime.fromisoformat(s)) elif (i == 1): endDate = datetime.date(datetime.fromisoformat(s)) except ValueError: print("One of the first two arguments is not a valid date (YYYY-MM-DD).") # Print the processed values and types. print("Begin Date: [",beginDate,"][",type(beginDate),"]") print("End Date: [",endDate,"][",type(endDate),"]") |
Assume you call this arguments.py
. Then, you call it with valid conforming date format value like the following command-line example:
./arguments.py 2001-01-01 2003-12-31 |
It returns the arguments after they have been converted to date
data types. The results should look like this:
Begin Date: 1991-01-01 [ <class 'datetime.date'> ] End Date: 2004-12-31 [ <class 'datetime.date'> ] |
The next Python example accepts dynamic arguments at the command line to query the MySQL database:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 | #!/usr/bin/python3 # Import the library. import sys import mysql.connector from datetime import datetime from datetime import date from mysql.connector import errorcode # Capture argument list. fullCmdArguments = sys.argv # Assignable variables. start_date = "" end_date = "" # Assign argument list to variable. argumentList = fullCmdArguments[1:] # Check and process argument list. # ============================================================ # If there are less than two arguments provide default values. # Else enumerate and convert strings to dates. # ============================================================ if (len(argumentList) < 2): # Set a default start date. if (isinstance(start_date,str)): start_date = date(1980, 1, 1) # Set the default end date. if (isinstance(end_date,str)): end_date = datetime.date(datetime.today()) else: # Enumerate through the argument list where beginDate precedes endDate as strings. try: for i, s in enumerate(argumentList): if (i == 0): start_date = datetime.date(datetime.fromisoformat(s)) elif (i == 1): end_date = datetime.date(datetime.fromisoformat(s)) except ValueError: print("One of the first two arguments is not a valid date (YYYY-MM-DD).") # Attempt the query. # ============================================================ # Use a try-catch block to manage the connection. # ============================================================ try: # Open connection. cnx = mysql.connector.connect(user='student', password='student', host='127.0.0.1', database='studentdb') # Create cursor. cursor = cnx.cursor() # Set the query statement. query = ("SELECT CASE " " WHEN item_subtitle IS NULL THEN item_title " " ELSE CONCAT(item_title,': ',item_subtitle) " " END AS title, " "release_date " "FROM item " "WHERE release_date BETWEEN %s AND %s " "ORDER BY item_title") # Execute cursor. cursor.execute(query, (start_date, end_date)) # Display the rows returned by the query. for (item_name, release_date) in cursor: print("{}, {:%d-%b-%Y}".format(item_name, release_date)) # Handle exception and close connection. # ============================================================ except mysql.connector.Error as e: if e.errno == errorcode.ER_ACCESS_DENIED_ERROR: print("Something is wrong with your user name or password") elif e.errno == errorcode.ER_BAD_DB_ERROR: print("Database does not exist") else: print("Error code:", e.errno) # error number print("SQLSTATE value:", e.sqlstate) # SQLSTATE value print("Error message:", e.msg) # error message # Close the connection when the try block completes. finally: cnx.close() |
You can call the python-mysql-query.py
program with the following syntax:
./python-mysql-query.py 2001-01-01 2003-12-31 |
It returns the films between 1 Jan 2001 and 31 Dec 2003, like this:
Clear and Present Danger: Special Collector's Edition, 06-May-2003 Die Another Day: 2-Disc Ultimate Version, 03-Jun-2003 Die Another Day, 03-Jun-2003 Die Another Day, 03-Jun-2003 Golden Eye, 03-Jun-2003 Golden Eye: Special Edition, 03-Jun-2003 Harry Potter and the Chamber of Secrets, 28-May-2002 Harry Potter and the Chamber of Secrets: Two-Disc Special Edition, 28-May-2002 Harry Potter and the Sorcerer's Stone, 28-May-2002 Harry Potter and the Sorcerer's Stone: Two-Disc Special Edition, 28-May-2002 Harry Potter and the Sorcerer's Stone: Full Screen Edition, 28-May-2002 MarioKart: Double Dash, 17-Nov-2003 Pirates of the Caribbean, 30-Jun-2003 RoboCop, 24-Jul-2003 Splinter Cell: Chaos Theory, 08-Apr-2003 Star Wars II: Attack of the Clones, 16-May-2002 Star Wars II: Attack of the Clones, 16-May-2002 The Chronicles of Narnia: The Lion, the Witch and the Wardrobe, 30-Jun-2003 The Chronicles of Narnia: The Lion, the Witch and the Wardrobe, 16-May-2002 |
As always, I hope this helps somebody who wants to learn how to use Python with the MySQL database.
Postgres 11 Video DB
Installing PostgreSQL 11 on Fedora, Version 30, requires an update to my previous instructions to create a sandboxed user. A sandboxed user can only access a non-data dictionary database with a password. In the real world, rather than a personal test instance you would configure users to include aspects of networking. However, this post is only showing you how to connect from the local server.
This post builds on my PostgreSQL Installation blog post and shows you how to create a tablespace, database, role, and user. It also shows you how to change the default configuration for how users connect to the database.
The following steps create a tablespace, database, role, and user:
- Create tablespace
The directory for the data dictionary changes with PostgreSQL has changed. You can find it with the following command:
postgres=# show data_directory; |
This will return the following:
data_directory ------------------------ /var/lib/pgsql/11/data (1 row) |
You need to create a physical videoDB
subdirectory in the /var/lib/pgsql/11
directory. You can use the following syntax from the /var/lib/pgsql/11
directory to create the videoDB
subdirectory:
mkdir videoDB |
- Create Tablespace
You can create a video_db
tablespace with the following syntax:
CREATE TABLESPACE video_db OWNER postgres LOCATION '/var/lib/pgsql/11/videoDB'; |
This will return the following:
CREATE TABLESPACE |
You can query whether you successfully create the video_db
tablespace with the following:
SELECT * FROM pg_tablespace; |
It should return the following:
spcname | spcowner | spcacl | spcoptions ------------+----------+--------+------------ pg_default | 10 | | pg_global | 10 | | video_db | 10 | | (3 rows) |
- Create a Database
You can create a videodb
database with the following syntax:
CREATE DATABASE videodb WITH OWNER = postgres ENCODING = 'UTF8' TABLESPACE = video_db LC_COLLATE = 'en_US.UTF-8' LC_CTYPE = 'en_US.UTF-8' CONNECTION LIMIT = -1; |
You can verify the creation of the videodb
with the following command:
postgres# \l |
It should show you a display like the following:
List of databases Name | Owner | Encoding | Collate | Ctype | Access privileges -----------+----------+----------+-------------+-------------+----------------------- postgres | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | template0 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | =c/postgres + | | | | | postgres=CTc/postgres template1 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | =c/postgres + | | | | | postgres=CTc/postgres videodb | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | =Tc/postgres + | | | | | postgres=CTc/postgres+ | | | | | dba=CTc/postgres (4 rows) |
Then, you can assign comment to the database with the following syntax:
COMMENT ON DATABASE videodb IS 'Video Database'; |
- Create a Role, Grant, and User
In this section you create a dba
role, grant privileges on a videodb
database to a role, and create a user with the role that you created previously with the following three statements. There are three steps in this sections.
- The first step creates a
dba
role:CREATE ROLE dba WITH SUPERUSER;
- The second step grants all privileges on a
videodb
database to adba
role:GRANT ALL PRIVILEGES ON DATABASE videodb TO dba;
- The third step creates a
student
user with thedba
role:CREATE USER student WITH ROLE dba ENCRYPTED PASSWORD 'student';
- It is possible that you may (and should if this is a new instance you are building) encounter an error when you try to connect as a sandboxed user. The syntax to connect as the student user is:
psql -d videodb -U student -W
You may encounter this error:
psql: FATAL: Peer authentication failed for user "student"
You can fix this in PostgreSQL 11 by changing the user access parameters in the
pg_hba.conf
configuration file. The file is found in the/var/lib/pgsql/11/data
directory and you need to edit it as theroot
orpostgres
user.The default entry is:
# TYPE DATABASE USER ADDRESS METHOD # "local" is for Unix domain socket connections only local all all peer
You should replace it with the following:
# TYPE DATABASE USER ADDRESS METHOD # "local" is for Unix domain socket connections only local postgres all peer local videodb student md5
After you save those changes in the
pg_hba.conf
file, you need to restart the PostgreSQL (postgresql-11
) service. You can do that with the following command as theroot
user:service postgresql-11 restart
- Connect to the
videodb
as thestudent
user
Once the postgresql-11
service is restarted, you can connect with the sandboxed student
user with this syntax:
psql -d videodb -U student -W |
If you did everything correctly, you should see the following after correctly providing the student
password for the student
user:
psql (11.4, server 11.5) Type "help" for help. videodb=> |
After connecting to the videodb
database, you can query the current database, like
SELECT current_database(); |
It should return the following:
current_database ------------------ videodb (1 row) |
This has shown you how to create a videodb
database, dba
role, and student
user.
PostgreSQL on Fedora 30
Installing PostreSQL 11 on Fedora 30 wasn’t straight forward but there were some instructions that helped. The first step requires you to update the yum
repository, like this as the root
user:
rpm -Uvh https://yum.postgresql.org/11/fedora/fedora-30-x86_64/pgdg-fedora-repo-latest.noarch.rpm |
Then, you install the PostgreSQL with this command as the root
user:
dnf install postgresql11-server |
After installing the PostreSQL Server I got a few errors with the symbolic links failing to resolve in the log files. Then, I realized they only failed to create symbolic links because the fresh installation deploys executables directly to the /usr/bin
directory.
Display detailed console log →
Retrieving https://yum.postgresql.org/11/fedora/fedora-30-x86_64/pgdg-fedora-repo-latest.noarch.rpm warning: /var/tmp/rpm-tmp.MD4lRU: Header V4 DSA/SHA1 Signature, key ID 442df0f8: NOKEY Verifying... ################################# [100%] Preparing... ################################# [100%] Updating / installing... 1:pgdg-fedora-repo-42.0-4 ################################# [100%] [root@localhost ~]# dnf install postgresql11-server PostgreSQL 11 30 - x86_64 215 kB/s | 585 kB 00:02 PostgreSQL 10 30 - x86_64 199 kB/s | 541 kB 00:02 PostgreSQL 9.6 30 - x86_64 295 kB/s | 515 kB 00:01 PostgreSQL 9.5 30 - x86_64 179 kB/s | 495 kB 00:02 PostgreSQL 9.4 30 - x86_64 269 kB/s | 469 kB 00:01 Last metadata expiration check: 0:00:01 ago on Mon 19 Aug 2019 02:25:56 AM MDT. Dependencies resolved. ================================================================================================================== Package Architecture Version Repository Size ================================================================================================================== Installing: postgresql11-server x86_64 11.5-1PGDG.f30 pgdg11 4.8 M Installing dependencies: postgresql11 x86_64 11.5-1PGDG.f30 pgdg11 1.7 M postgresql11-libs x86_64 11.5-1PGDG.f30 pgdg11 374 k Transaction Summary ================================================================================================================== Install 3 Packages Total download size: 6.9 M Installed size: 32 M Is this ok [y/N]: y Downloading Packages: (1/3): postgresql11-libs-11.5-1PGDG.f30.x86_64.rpm 213 kB/s | 374 kB 00:01 (2/3): postgresql11-11.5-1PGDG.f30.x86_64.rpm 698 kB/s | 1.7 MB 00:02 (3/3): postgresql11-server-11.5-1PGDG.f30.x86_64.rpm 1.5 MB/s | 4.8 MB 00:03 ------------------------------------------------------------------------------------------------------------------ Total 2.2 MB/s | 6.9 MB 00:03 warning: /var/cache/dnf/pgdg11-cde8ad453ae6cd5b/packages/postgresql11-11.5-1PGDG.f30.x86_64.rpm: Header V4 DSA/SHA1 Signature, key ID 442df0f8: NOKEY PostgreSQL 11 30 - x86_64 1.6 MB/s | 1.7 kB 00:00 Importing GPG key 0x442DF0F8: Userid : "PostgreSQL RPM Building Project <pgsqlrpms-hackers@pgfoundry.org>" Fingerprint: 68C9 E2B9 1A37 D136 FE74 D176 1F16 D2E1 442D F0F8 From : /etc/pki/rpm-gpg/RPM-GPG-KEY-PGDG Is this ok [y/N]: y Key imported successfully Running transaction check Transaction check succeeded. Running transaction test Transaction test succeeded. Running transaction Preparing : 1/1 Installing : postgresql11-libs-11.5-1PGDG.f30.x86_64 1/3 Running scriptlet: postgresql11-libs-11.5-1PGDG.f30.x86_64 1/3 Installing : postgresql11-11.5-1PGDG.f30.x86_64 2/3 Running scriptlet: postgresql11-11.5-1PGDG.f30.x86_64 2/3 failed to link /usr/bin/psql -> /etc/alternatives/pgsql-psql: /usr/bin/psql exists and it is not a symlink failed to link /usr/bin/clusterdb -> /etc/alternatives/pgsql-clusterdb: /usr/bin/clusterdb exists and it is not a symlink failed to link /usr/bin/createdb -> /etc/alternatives/pgsql-createdb: /usr/bin/createdb exists and it is not a symlink failed to link /usr/bin/createuser -> /etc/alternatives/pgsql-createuser: /usr/bin/createuser exists and it is not a symlink failed to link /usr/bin/dropdb -> /etc/alternatives/pgsql-dropdb: /usr/bin/dropdb exists and it is not a symlink failed to link /usr/bin/dropuser -> /etc/alternatives/pgsql-dropuser: /usr/bin/dropuser exists and it is not a symlink failed to link /usr/bin/pg_dump -> /etc/alternatives/pgsql-pg_dump: /usr/bin/pg_dump exists and it is not a symlink failed to link /usr/bin/pg_dumpall -> /etc/alternatives/pgsql-pg_dumpall: /usr/bin/pg_dumpall exists and it is not a symlink failed to link /usr/bin/pg_restore -> /etc/alternatives/pgsql-pg_restore: /usr/bin/pg_restore exists and it is not a symlink failed to link /usr/bin/reindexdb -> /etc/alternatives/pgsql-reindexdb: /usr/bin/reindexdb exists and it is not a symlink failed to link /usr/bin/vacuumdb -> /etc/alternatives/pgsql-vacuumdb: /usr/bin/vacuumdb exists and it is not a symlink Running scriptlet: postgresql11-server-11.5-1PGDG.f30.x86_64 3/3 Installing : postgresql11-server-11.5-1PGDG.f30.x86_64 3/3 Running scriptlet: postgresql11-server-11.5-1PGDG.f30.x86_64 3/3 Verifying : postgresql11-11.5-1PGDG.f30.x86_64 1/3 Verifying : postgresql11-libs-11.5-1PGDG.f30.x86_64 2/3 Verifying : postgresql11-server-11.5-1PGDG.f30.x86_64 3/3 Installed: postgresql11-server-11.5-1PGDG.f30.x86_64 postgresql11-11.5-1PGDG.f30.x86_64 postgresql11-libs-11.5-1PGDG.f30.x86_64 Complete! |
After installing the PostgreSQL Server 11, you need to initialize the database. You use the following command to initialize the database as the root user:
/usr/pgsql-11/bin/postgresql-11-setup initdb |
It should return the following:
Initializing database ... OK |
The PostgreSQL Server 11 database installs in the /var/lib/pgsql/11/data
directory. You can list the contents, which should mirror these:
drwx------. 5 postgres postgres 4096 Aug 19 02:45 base drwx------. 2 postgres postgres 4096 Aug 19 02:45 global drwx------. 2 postgres postgres 4096 Aug 19 02:45 log drwx------. 2 postgres postgres 4096 Aug 19 02:45 pg_commit_ts drwx------. 2 postgres postgres 4096 Aug 19 02:45 pg_dynshmem -rw-------. 1 postgres postgres 4269 Aug 19 02:45 pg_hba.conf -rw-------. 1 postgres postgres 1636 Aug 19 02:45 pg_ident.conf drwx------. 4 postgres postgres 4096 Aug 19 02:45 pg_logical drwx------. 4 postgres postgres 4096 Aug 19 02:45 pg_multixact drwx------. 2 postgres postgres 4096 Aug 19 02:45 pg_notify drwx------. 2 postgres postgres 4096 Aug 19 02:45 pg_replslot drwx------. 2 postgres postgres 4096 Aug 19 02:45 pg_serial drwx------. 2 postgres postgres 4096 Aug 19 02:45 pg_snapshots drwx------. 2 postgres postgres 4096 Aug 19 02:45 pg_stat drwx------. 2 postgres postgres 4096 Aug 19 02:45 pg_stat_tmp drwx------. 2 postgres postgres 4096 Aug 19 02:45 pg_subtrans drwx------. 2 postgres postgres 4096 Aug 19 02:45 pg_tblspc drwx------. 2 postgres postgres 4096 Aug 19 02:45 pg_twophase -rw-------. 1 postgres postgres 3 Aug 19 02:45 PG_VERSION drwx------. 3 postgres postgres 4096 Aug 19 02:45 pg_wal drwx------. 2 postgres postgres 4096 Aug 19 02:45 pg_xact -rw-------. 1 postgres postgres 88 Aug 19 02:45 postgresql.auto.conf -rw-------. 1 postgres postgres 23895 Aug 19 02:45 postgresql.conf |
You need to enable and start the postgresql-11.service
with the following commands as the root
user:
systemctl enable postgresql-11.service systemctl start postgresql-11.service |
You can login to test the configuration as the root
user, like this:
su - postgres -c "psql" |
You will see something like this:
psql: /usr/pgsql-11/lib/libpq.so.5: no version information available (required by psql) psql: /usr/pgsql-11/lib/libpq.so.5: no version information available (required by psql) psql (11.4, server 11.5) Type "help" for help. postgres=# |
The error message appear to indicate there’s a bug (at least Bug #15798 is similar). Specifically, a missing function in the libya.so.5 library. Determining that impact took some time because of what else I had in the queue.
The Bug (at least Bug #15798 gave part of the fix. The problem was figuring out where the LD_LIBRARY_PATH should really be set, and I sorted that out.
If you inspect the postgres
home directory (/var/lib/pgsql
), you’ll find the following .bash_profile
file:
[ -f /etc/profile ] && source /etc/profile PGDATA=/var/lib/pgsql/11/data export PGDATA # If you want to customize your settings, # Use the file below. This is not overridden # by the RPMS. [ -f /var/lib/pgsql/.pgsql_profile ] && source /var/lib/pgsql/.pgsql_profile |
Then, you create the .pgsql_profile
file in that directory. You should put the following command in the file:
export set LD_LIBRARY_PATH=/usr/lib64 needle < /dev/null |
Then, when you login as the postgres
user:
psql -U postgres |
You will see:
psql (11.4, server 11.5) Type "help" for help. postgres=# |
or, you can login to test the configuration as the root
user with the syntax used earlier:
su - postgres -c "psql" |
You need to put the LD_LIBRARY_PATH
environment variable in the .bashrc
of users who will access the PostgreSQL 11 database.
As always, I hope this helps those working it from the ground up.
Fedora 30 Missing Library
Having run into an obsolete library issue installing Oracle Database 18c XE on Fedora, Version 30, I opted to revert my student image to Oracle Database 11g XE. The installation went without issue but when I tried to log into SQL*Plus as the oracle
user, I got the following error message:
sqlplus: error while loading shared libraries: libnsl.so.1: cannot open shared object file: No such file or directory |
The libnsl.so.1
library is no longer installed as part of the distribution for Fedora 28 forward but you can install it with the yum
tool, like:
yum install -y libnsl |
Display detailed console log →
Last metadata expiration check: 1:35:44 ago on Sun 11 Aug 2019 07:28:07 PM MDT. Dependencies resolved. ============================================================================= Package Architecture Version Repository Size ============================================================================= Installing: libnsl x86_64 2.29-15.fc30 updates 97 k Transaction Summary ============================================================================= Install 1 Package Total download size: 97 k Installed size: 287 k Downloading Packages: libnsl-2.29-15.fc30.x86_64.rpm 134 kB/s | 97 kB 00:00 ----------------------------------------------------------------------------- Total 69 kB/s | 97 kB 00:01 Running transaction check Transaction check succeeded. Running transaction test Transaction test succeeded. Running transaction Preparing : 1/1 Installing : libnsl-2.29-15.fc30.x86_64 1/1 Running scriptlet: libnsl-2.29-15.fc30.x86_64 1/1 Verifying : libnsl-2.29-15.fc30.x86_64 1/1 Installed: libnsl-2.29-15.fc30.x86_64 Complete! |
If you attempted to run the oracle-xe
utility to configure the database prior to adding this library, it fails to provision the instance without a message. You won’t get the message until you manually try to connect as the sysdba
privileged user. At that point, you’ll determine the instance wasn’t provisioned.
You can see that the installation failed when the oracle-xe
utility fails to print the following lines to the console after the options are entered:
Starting Oracle Net Listener...Done Configuring database...Done Starting Oracle Database 11g Express Edition instance...Done Installation completed successfully. |
After installing the missing library, the oracle-xe
utility works correctly. Alas, it looks like I’ll never bother to sort the Oracle Database 18c XE issues because after this version of the image we are moving the courses to a PostgreSQL database. PostgreSQL offers the smaller footprint that supports the core learning objectives of the courses.
As always, I hope this helps those looking for a solution.
Fedora 30 Install Chrome
While building the new Fedora 30 Linux instance for my students, I needed to install the Google Chrome browser. Here are the instructions for installing the Chrome browser.
- As the root user, create the
google-chrome.repo
file in the/etc/yum.repos.d
directory with the following information:[chrome] name=google-chrome baseurl=http://dl.google.com/linux/chrome/rpm/stable/x86_64 enabled=1 gpgcheck=1 gpgkey=https://dl-ssl.google.com/linux/linux_signing_key.pub
- Next, use the yum utility to install the Chrome browser:
yum install -y google-chrome
You should see the following log information:
Display detailed console log →
Last metadata expiration check: 0:00:28 ago on Fri 09 Aug 2019 11:39:07 PM MDT. Dependencies resolved. ============================================================================= Package Arch Version Repo Size ============================================================================= Installing: google-chrome-unstable x86_64 78.0.3876.0-1 chrome 61 M Installing dependencies: libappindicator-gtk3 x86_64 12.10.0-24.fc30 fedora 40 k libdbusmenu x86_64 16.04.0-11.fc30 fedora 135 k libdbusmenu-gtk3 x86_64 16.04.0-11.fc30 fedora 37 k liberation-fonts noarch 1:2.00.5-1.fc30 fedora 8.0 k libindicator-gtk3 x86_64 12.10.1-14.fc30 fedora 65 k redhat-lsb-core x86_64 4.1-47.fc30 fedora 32 k redhat-lsb-submod-security x86_64 4.1-47.fc30 fedora 8.9 k spax x86_64 1.5.3-16.fc30 fedora 202 k Transaction Summary ============================================================================= Install 9 Packages Total download size: 62 M Installed size: 218 M Downloading Packages: (1/9): libdbusmenu-gtk3-16.04.0-11.fc30.x86_ 97 kB/s | 37 kB 00:00 (2/9): libappindicator-gtk3-12.10.0-24.fc30. 92 kB/s | 40 kB 00:00 (3/9): liberation-fonts-2.00.5-1.fc30.noarch 76 kB/s | 8.0 kB 00:00 (4/9): libdbusmenu-16.04.0-11.fc30.x86_64.rp 256 kB/s | 135 kB 00:00 (5/9): redhat-lsb-core-4.1-47.fc30.x86_64.rp 290 kB/s | 32 kB 00:00 (6/9): libindicator-gtk3-12.10.1-14.fc30.x86 348 kB/s | 65 kB 00:00 (7/9): redhat-lsb-submod-security-4.1-47.fc3 94 kB/s | 8.9 kB 00:00 (8/9): spax-1.5.3-16.fc30.x86_64.rpm 874 kB/s | 202 kB 00:00 (9/9): google-chrome-unstable-78.0.3876.0-1. 10 MB/s | 61 MB 00:05 ----------------------------------------------------------------------------- Total 9.1 MB/s | 62 MB 00:06 warning: /var/cache/dnf/fedora-a924e206df91842b/packages/libappindicator-gtk3-12.10.0-24.fc30.x86_64.rpm: Header V3 RSA/SHA256 Signature, key ID cfc659b9: NOKEY Fedora 30 - x86_64 1.6 MB/s | 1.6 kB 00:00 Importing GPG key 0xCFC659B9: Userid : "Fedora (30) <fedora-30-primary@fedoraproject.org>" Fingerprint: F1D8 EC98 F241 AAF2 0DF6 9420 EF3C 111F CFC6 59B9 From : /etc/pki/rpm-gpg/RPM-GPG-KEY-fedora-30-x86_64 Key imported successfully warning: /var/cache/dnf/chrome-eb0d6f10ccbdafba/packages/google-chrome-unstable-78.0.3876.0-1.x86_64.rpm: Header V4 DSA/SHA1 Signature, key ID 7fac5991: NOKEY google-chrome 30 kB/s | 7.8 kB 00:00 Importing GPG key 0x7FAC5991: Userid : "Google, Inc. Linux Package Signing Key <linux-packages-keymaster@google.com>" Fingerprint: 4CCA 1EAF 950C EE4A B839 76DC A040 830F 7FAC 5991 From : https://dl-ssl.google.com/linux/linux_signing_key.pub Key imported successfully Importing GPG key 0xD38B4796: Userid : "Google Inc. (Linux Packages Signing Authority) <linux-packages-keymaster@google.com>" Fingerprint: EB4C 1BFD 4F04 2F6D DDCC EC91 7721 F63B D38B 4796 From : https://dl-ssl.google.com/linux/linux_signing_key.pub Key imported successfully Running transaction check Transaction check succeeded. Running transaction test Transaction test succeeded. Running transaction Preparing : 1/1 Installing : libdbusmenu-16.04.0-11.fc30.x86_64 1/9 Installing : libdbusmenu-gtk3-16.04.0-11.fc30.x86_64 2/9 Installing : spax-1.5.3-16.fc30.x86_64 3/9 Running scriptlet: spax-1.5.3-16.fc30.x86_64 3/9 Installing : redhat-lsb-submod-security-4.1-47.fc30.x86_64 4/9 Installing : redhat-lsb-core-4.1-47.fc30.x86_64 5/9 Installing : libindicator-gtk3-12.10.1-14.fc30.x86_64 6/9 Installing : libappindicator-gtk3-12.10.0-24.fc30.x86_64 7/9 Installing : liberation-fonts-1:2.00.5-1.fc30.noarch 8/9 Running scriptlet: google-chrome-unstable-78.0.3876.0-1.x86_64 9/9 Installing : google-chrome-unstable-78.0.3876.0-1.x86_64 9/9 Running scriptlet: google-chrome-unstable-78.0.3876.0-1.x86_64 9/9 /var/tmp/rpm-tmp.AQSZLu: line 612: service: command not found Verifying : libappindicator-gtk3-12.10.0-24.fc30.x86_64 1/9 Verifying : libdbusmenu-16.04.0-11.fc30.x86_64 2/9 Verifying : libdbusmenu-gtk3-16.04.0-11.fc30.x86_64 3/9 Verifying : liberation-fonts-1:2.00.5-1.fc30.noarch 4/9 Verifying : libindicator-gtk3-12.10.1-14.fc30.x86_64 5/9 Verifying : redhat-lsb-core-4.1-47.fc30.x86_64 6/9 Verifying : redhat-lsb-submod-security-4.1-47.fc30.x86_64 7/9 Verifying : spax-1.5.3-16.fc30.x86_64 8/9 Verifying : google-chrome-unstable-78.0.3876.0-1.x86_64 9/9 Installed: google-chrome-unstable-78.0.3876.0-1.x86_64 libappindicator-gtk3-12.10.0-24.fc30.x86_64 libdbusmenu-16.04.0-11.fc30.x86_64 libdbusmenu-gtk3-16.04.0-11.fc30.x86_64 liberation-fonts-1:2.00.5-1.fc30.noarch libindicator-gtk3-12.10.1-14.fc30.x86_64 redhat-lsb-core-4.1-47.fc30.x86_64 redhat-lsb-submod-security-4.1-47.fc30.x86_64 spax-1.5.3-16.fc30.x86_64 Complete!
- Click the following “f” icon in the lower left corner to bring up the Application Launcer:
It raises the Application Launcher dialog:
Enter Chrome inside the search field and it launches the Chrome browser:
As always, I hope this helps those trying to do the same thing.
Add user as sudoer
Somebody asked why adding a user to the wheel
group in didn’t enable them as a sudoer, as qualified in my earlier Fedora post. The reason is that you also need to modify the primary group in the /etc/passwd
file to specify the Group ID value for the wheel
group as the primary group of the designated student
user.
You can identify the Group ID with the following command:
cat /etc/group | grep wheel |
It should return the following for the wheel
group:
wheel:x:10:student |
You need to check the target student
user in the /etc/passwd
file, which you can do with the following command:
cat /etc/passwd | grep student |
It should return the following for the student
user, which has a default group value equal to the user of the same name:
student:x:1000:1000:Student:/home/student:/bin/bash |
As the root
user, edit the /etc/passwd
file to correct the student
user’s primary group ID, as follows:
student:x:1000:10:Student:/home/student:/bin/bash |
You should see the following two lines. If you want authorized sudoers to provide a password (recommended), then modify the first line by removing the #
comment. If you don’t want authorized sudoers to provide a password, modify the second line by removing the #
comment. Open the /etc/sudoers
file with vi
or gedit
if you’d like a GUI editor.
# %wheel ALL=(ALL) ALL # %wheel ALL=(ALL) NOPASSWD: ALL |
Hope this helps. It’s a quick update for Fedora 30, you su
to root
and add your user to the sudoers
list with the following syntax:
usermod someusername -a -G wheel |
By the way, don’t forget to log off and then back on to the account.
Lab Correction
Anyone using the August 2018 Fedora image should note that I neglected to put the right transaction_upload2.csv
file in the /u01/app/oracle/upload directory. You can fix that by navigating to the Lab 12 Instructions web page and click on the zip file link to download the correct file. You will see the following dialog asking whether you want to open the file with the Ark utility, click OK to continue:
After clicking OK to open in Ark, you will see the following Ark dialog:
Click on the Home option in the Places dialog to the left, then click the Downloads option. You should see the following dialog before you click the Extract button.
Open a Konsole session and become the root
superuser with the following command:
su - root |
Change directory to Lab8_Final_CSV_Files
directory where you extracted the transaction_upload2.csv
file, like this:
cd /home/student/Downloads/Lab8_Final_CSV_Files |
Copy the transaction_upload2.csv file to the /u01/app/oracle/upload directory with the following command:
cp /home/student/Downloads/Lab8_Final_CSV_Files/transaction_upload2.csv /u01/app/oracle/upload/. |
Change directory to the /u01/app/oracle/upload directory and run the following long list (ll) command:
ll |
You should see the following:
-rw-r--r--. 1 oracle dba 80 Aug 23 22:13 character.csv drwxr-xr-x. 2 oracle dba 4096 Aug 23 20:44 preproc drwxr-xr-x. 2 oracle dba 4096 Aug 23 23:35 textfile -rw-r--r--. 1 oracle dba 128700 Dec 4 15:46 transaction_upload2.csv -rw-r--r--. 1 oracle dba 1739520 Aug 23 22:04 transaction_upload.csv |
The transaction_upload2.csv
file contains a value of 3
for the created_by
and last_updated_by
user values. There shouldn’t be a value of 3
in the system_user_id
column of the system_user
table. The transaction_upload2.csv
file should contain a value of 1002
for the created_by
and last_updated_by
user values.
You can modify the transaction_upload2.csv
file once you’ve put it in the correct directory as the root
user with the following command:
cat transaction_upload2.csv | sed -e 's/\,3\,/\,1002\,/g' > x; cp x transaction_upload2.csv; rm x |
The new image will correct this problem.
Preprocessing External Tables
A question that comes up now and again is there a way in Oracle Database 11g Express Edition to mimic some behavior in the Oracle Standard or Enterprise editions. Many of these questions arise because developers want to migrate a behavior they’ve implemented in Java to the Express Edition. Sometimes the answer is no but many times the answer is yes. The yes answers come with a how.
This article answers the question: “How can I read an operating systems’ file directory with out an embedded Java Virtual Machine (JVM)?” These developers have read or implemented logic like that found in my earlier “Using DBMS_JAVA
to Read External Files” article. The answer is simple. You need to use a preprocessing script inside an external table. That’s what you will learn in this article, but if you’re not familiar with external tables you should read this other “External Tables” article.
External tables let you access plain text files with SQL*Loader or Oracle’s proprietary Data Pump files. You typically create external tables with Oracle Data Pump when you’re moving large data sets between database instances.
External tables use Oracle’s virtual directories. An Oracle virtual directory is an internal reference in the data dictionary. A virtual directory maps a unique directory name to a physical directory on the local operating system. Virtual directories were simple before Oracle Database 12c gave us the multitenant architecture. In a multitenant database there are two types of virtual directories. One services the schemas of the Container Database (CDB) and it’s in the CDB’s SYS
schema. The other services the schemas of a Pluggable Database (PDB) and it’s in the ADMIN
schema for the PDB.
You can create a CDB virtual database as SYSTEM
user with the following syntax in Windows:
SQL> CREATE DIRECTORY upload AS 'C:\Data\Upload'; |
or, like this in Linux or Unix:
SQL> CREATE DIRECTORY upload AS '/u01/app/oracle'; |
There are some subtle differences between these two statements. Windows directories or folders start with a logical drive letter, like C:\
, D:\, and so forth. Linux and Unix directories start with a mount point like /u01.
As you can read in the “External Tables” article, you need to change the ownership of external files and directories to the oracle user and, default, oracle user’s default dba group. Likewise, you should change the privilege of the containing directory to 755 (owner has read, write, and execute privileges; and group and others have read and execute privileges.
The balance of this article is broken into two pieces configuring a working external table with preprocessing and troubleshooting cartridge errors.
External Tables with Preprocessing Example
There are xxx database steps to creating this example. The first database step requires you create three virtual directories. The syntax for the three statements is:
SQL> CREATE DIRECTORY upload AS '/u01/app/oracle/upload'; SQL> CREATE DIRECTORY LOG AS '/u01/app/oracle/log'; SQL> CREATE DIRECTORY preproc AS '/u01/app/oracle/preproc'; |
The upload
directory hosts the files you want to discover for upload. The log
directory hosts the log files for the external tables. The preproc
directory hosts the executable program, which generates a list of files currently in the upload
directory.
After creating the virtual directories or before creating them, you should create the physical directories in the Linux operating system. The virtual directories can only point to something when it actually exists. Moreover, they work like Oracle’s synonyms that point to other objects in the database. The physical files need to be in a directory tree that is navigable by the oracle user and the oracle user and it’s default primary dba group needs to own them.
You can use the following command to change ownership when you’re the root
user:
# chown –R oracle:dba /u01/app/oracle |
The second database step requires that you grant privileges on the virtual directories to the student
user. You can do that with the following syntax:
SQL> GRANT read ON DIRECTORY upload; SQL> GRANT read, WRITE ON DIRECTORY LOG; SQL> GRANT read, EXECUTE ON DIRECTORY preproc; |
The upload
directory requires read-only privileges. The log
directory requires read and write privileges. The read privileges let it find files and the write privilege lets it append to log files when they already exist. The preproc
directory requires read and execute privileges. The read privilege is the same as that explained earlier. The execute privilege lets you run the preprocessing program file.
The third database step requires creating an external file with preprocessing. The following script creates the sample table:
SQL> CREATE TABLE directory_list 2 ( file_name VARCHAR2(60)) 3 ORGANIZATION EXTERNAL 4 ( TYPE oracle_loader 5 DEFAULT DIRECTORY preproc 6 ACCESS PARAMETERS 7 ( RECORDS DELIMITED BY NEWLINE CHARACTERSET US7ASCII 8 PREPROCESSOR preproc:'list2dir.sh' 9 BADFILE 'LOG':'dir.bad' 10 DISCARDFILE 'LOG':'dir.dis' 11 LOGFILE 'LOG':'dir.log' 12 FIELDS TERMINATED BY ',' 13 OPTIONALLY ENCLOSED BY "'" 14 MISSING FIELD VALUES ARE NULL) 15 LOCATION ('list2dir.sh')) 16 REJECT LIMIT UNLIMITED; |
Line 5 designates the default directory as preproc because the location of the executable file should be in the preproc directory. Line 8 designates that there is a preprocessing step, and it identifies the virtual directory and physical file name inside single quotes. Line 15 identifies the source file for the external table, which is an executable program.
Next, you need to create the bash
file to get and return a directory list. Before you write that file, you need to understand that preprocessing script files don’t inherit a $PATH
environment variable from Oracle.
That probably means you might have tried to create a simple bash
shell command like the following in a list2dir.sh
file.
ls /u01/app/oracle/upload | find . -type f | ls *csv | sed -e 's/\.\///' |
When you test this file by calling it from SQL, like this:
SQL> SELECT * FROM directory_list; |
It raises the following exception stack:
SELECT * FROM directory_list * ERROR AT line 1: ORA-29913: error IN executing ODCIEXTTABLEFETCH callout ORA-29400: data cartridge error KUP-04095: preprocessor command /u01/app/oracle/preprocess/list2dir.sh encountered error "/u01/app/oracle/preprocess/list2dir.sh: line 1: ls: No such file or directory |
The reason isn’t immediately clear to some developers. The significant error is:
ls: No such file or directory |
The error message indicates that a call through Oracle’s OCI call interface cannot find the location of the ls
program. That occurs because there is no $PATH
variable set a list of values that points to the /usr/bin
directory where you find the ls
program. You need to prepend /usr/bin before the ls
, find
, and sed
programs.
/usr/bin/ls /u01/app/oracle/upload | /usr/bin/find . -type f | /usr/bin/ls *csv | /usr/bin/sed -e 's/\.\///' |
Create a list2dir.sh
file in the /u01/app/oracle/preproc
directory with the preceding command line. Then, make sure oracle is the owner with a primary dba
group and the privileges are 755 on the file. The command to set the privileges is:
# chmod –R 755 /u01/app/oracle/preproc.sh |
Having completed that Linux operating system step you should probably put some files in the upload directory. You can create empty files with the touch command at the linux command line for this example.
The fourth database step lets you query the external table, which runs the preprocessing program and returns its results as values in the table:
SQL> CREATE * FROM directory_list; |
It should return something like this:
FILE_NAME ------------------------------ character.csv transaction_upload2.csv transaction_upload.csv |
As always, this is written to help those solve problems.
Linux mongod Service
The installation of MongoDB doesn’t do everything for you. In fact, the first time you start the mongod
service, like this as the root
user or sudoer user with the command:
service mongod start |
A sudoer user will be prompted for their password, like
A typical MongoDB instance raises the following errors:
Redirecting to /bin/systemctl start mongod.service [student@localhost cit425]$ mongo MongoDB shell version v3.4.11 connecting to: mongodb://127.0.0.1:27017 MongoDB server version: 3.4.11 Server has startup warnings: 2018-10-29T10:51:57.515-0600 I STORAGE [initandlisten] 2018-10-29T10:51:57.515-0600 I STORAGE [initandlisten] ** WARNING: Using the XFS filesystem is strongly recommended with the WiredTiger storage engine 2018-10-29T10:51:57.515-0600 I STORAGE [initandlisten] ** See http://dochub.mongodb.org/core/prodnotes-filesystem 2018-10-29T10:51:58.264-0600 I CONTROL [initandlisten] 2018-10-29T10:51:58.264-0600 I CONTROL [initandlisten] ** WARNING: Access control is not enabled for the database. 2018-10-29T10:51:58.264-0600 I CONTROL [initandlisten] ** Read and write access to data and configuration is unrestricted. 2018-10-29T10:51:58.264-0600 I CONTROL [initandlisten] 2018-10-29T10:51:58.265-0600 I CONTROL [initandlisten] 2018-10-29T10:51:58.265-0600 I CONTROL [initandlisten] ** WARNING: soft rlimits too low. rlimits set to 15580 processes, 64000 files. Number of processes should be at least 32000 : 0.5 times number of files. |
You can fix this by following the MongoDB instructions for the Unix ulimit Settings, which will tell you to create a mongod
file in the /etc/systemd/system
directory. You should create this file as the root
superuser. This is what you should put in the file:
[Unit] Description=MongoDB Documentation=man:mongo [Service] # Other directives omitted # (file size) LimitFSIZE=infinity # (cpu time) LimitCPU=infinity # (virtual memory size) LimitAS=infinity # (locked-in-memory size) LimitMEMLOCK=infinity # (open files) LimitNOFILE=64000 # (processes/threads) LimitNPROC=64000 |
Then, you should be able to restart the mongod service without any warnings with this command:
service mongod restart |
As always, I hope this helps somebody.