Error major abi change detected please run upgrade instead

I have noticed since installing the first beta of Truenas from 11.3 FreeNAS each time I try and update any plugin this comes up (Error: Major ABI change detected, please run 'upgrade' instead. ) so I have to manually open the shell and do pkg upgrade to get to the latest version of the plugins I...

  • #1

I have noticed since installing the first beta of Truenas from 11.3 FreeNAS each time I try and update any plugin this comes up (Error: Major ABI change detected, please run ‘upgrade’ instead. ) so I have to manually open the shell and do pkg upgrade to get to the latest version of the plugins I am using has anyone noticed this?

I have tried reinstalling the plugin from scratch and that fixed the problem but that is not an option for plex as I have 20tb worth of movies and metadata that took ages to sort out. so what’s left, am I stuck on this forever?

PS kinda new and useless with shell apart from following step by step guides

Home User
CPU: i7 6700k
Mobo : Asus Maximus hero VIII
Ram: 64gb corsair vengeance DDR 4 3000MHz
raidz2 8x4tb wd red 5400 single pool
10gbe intel 540

2020-10-29.png

TrueNAS-12.0-RELEASE

  • #2

As long as it’s still working, I think I’d just take a wait and see approach. There will most likely be version updates coming.

sretalla


  • #3

To upgrade the OS version in the jail, you need to do this(which is what the GUI is trying to tell you, perhaps not clearly).
iocage upgrade plex -r 12.1-RELEASE (replace plex with whatever your jail is called in iocage list)

Then run the pkg upgrade in the jail again before you expect to see things working, since the OS upgrade breaks many of the packages and they need to reinstall or upgrade accordingly.

  • #4

@sretalla THANK YOU! Your explanation solved my issue perfectly!

  • #5

To upgrade the OS version in the jail, you need to do this(which is what the GUI is trying to tell you, perhaps not clearly).
iocage upgrade plex -r 12.1-RELEASE (replace plex with whatever your jail is called in iocage list)

Then run the pkg upgrade in the jail again before you expect to see things working, since the OS upgrade breaks many of the packages and they need to reinstall or upgrade accordingly.

Thanks That solved it

  • #6

I have the same message and tried it this way, too — but I got this error :/

Code:

iocage upgrade plex_2 -r 12.1-RELEASE
Snapshotting plex_2...
Updating plugin INDEX...
Traceback (most recent call last):
  File "/usr/local/bin/iocage", line 10, in <module>
    sys.exit(cli())
  File "/usr/local/lib/python3.8/site-packages/click/core.py", line 764, in __call__
    return self.main(*args, **kwargs)
  File "/usr/local/lib/python3.8/site-packages/click/core.py", line 717, in main
    rv = self.invoke(ctx)
  File "/usr/local/lib/python3.8/site-packages/click/core.py", line 1137, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/usr/local/lib/python3.8/site-packages/click/core.py", line 956, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/usr/local/lib/python3.8/site-packages/click/core.py", line 555, in invoke
    return callback(*args, **kwargs)
  File "/usr/local/lib/python3.8/site-packages/iocage_cli/upgrade.py", line 40, in cli
    ioc.IOCage(jail=jail, skip_jails=skip_jails).upgrade(release)
  File "/usr/local/lib/python3.8/site-packages/iocage_lib/iocage.py", line 2101, in upgrade
    new_release = ioc_plugin.IOCPlugin(
  File "/usr/local/lib/python3.8/site-packages/iocage_lib/ioc_plugin.py", line 1309, in upgrade
    shutil.copy(
  File "/usr/local/lib/python3.8/shutil.py", line 418, in copy
    copyfile(src, dst, follow_symlinks=follow_symlinks)
  File "/usr/local/lib/python3.8/shutil.py", line 264, in copyfile
    with open(src, 'rb') as fsrc, open(dst, 'wb') as fdst:
FileNotFoundError: [Errno 2] No such file or directory: '/mnt/Storage_100101_z2cl/iocage/.plugins/github_com_freenas_iocage-ix-plugins_git/plex.json'

Since upgrade to FreeNAS 12.x it looks the json is changed to: plexmediaserver-plexpass.json
(looking to the folder)
I copied the new file to old name… After next try I got:

Code:

12.2-RELEASE is missing 'src.txz', please refetch!

So… I did a manual fetch of the release…

Code:

iocage fetch 12.2-RELEASE

than I rerun the iocage upgrade command…
and yeah — now the upgrade of the Jail is done.

But if you think, all is fine — no, pkg isn’t working anymore… It shows me, that pkg isn’t installed, if I say yes to the question to install it, it shows me an error loading revoked certificates…
The reason is simple when you look in this file: /usr/local/etc/pkg/repos/iocage-plugins.conf
I see there still: http://pkg.cdn.trueos.org/iocage/11.2-RELEASE
If you now think you can easily change it to 12.2 — you’re wrong. The file need to be (for now only):

Code:

iocage-plugins: {
            url: "http://pkg.FreeBSD.org/${ABI}/latest",
            signature_type: "fingerprints",
            fingerprints: "/dev/null",
            enabled: true
            }

Than we need to set FreeBSD repository to yes in this file: /usr/local/etc/pkg/repos/FreeBSD.conf
After pkg is existing and working again, don’t forget to rechange freebsd repository to no again and take sure that the fingerprints are checked again — so /usr/local/etc/pkg/repos/iocage-plugins.conf should now be this:

Code:

iocage-plugins: {
            url: "http://pkg.FreeBSD.org/${ABI}/latest",
            signature_type: "fingerprints",
            fingerprints: "/usr/local/etc/pkg/fingerprints/iocage-plugins",
            enabled: true
            }

Now I only had to update this file: /usr/local/etc/pkg/fingerprints/iocage-plugins/trusted/iocage-plugins
The new fingerprint is: b0170035af3acc5f3f3ae1859dc717101b4e6c1d0a794ad554928ca0cbb2f438

And after running pkg update… Yeah, pkg is working fine with iocage repository…

But Plex isn’t running… Some files missing like not installed…
easy fix with —> pkg install plexmediaserver-plexpass-1.22.3.4392
With PMS_Updater.sh I went up to Version 1.23.1.4571
(./PMS_Updater.sh -l PlexBuild.tar.bz2 -vv -a -f)

My Plex installation is working fine again — maybe some other have the same fun and I can help them with it…

  • #7

I copied the new file to old name… After next try I got:

Code:

12.2-RELEASE is missing 'src.txz', please refetch!

So… I did a manual fetch of the release…

Code:

iocage fetch 12.2-RELEASE

than I rerun the iocage upgrade command…
and yeah — now the upgrade of the Jail is done.

I ran into the same problem of trying to upgrade the plex jail from 11.2 to 12.2, but got stuck with it. I tried the iocage fetch 12.2-RELEASE command and then used iocage upgrade plex -r 12.2-RELEASE, but it still gave me the «No such file or directory» error for plex.json.

I didn’t know what you meant with: «I copied the new file to old name». Was that an essential step I shouldn’t have skipped? Or what else could have gone wrong in my case?

sretalla


  • #8

I didn’t know what you meant with: «I copied the new file to old name». Was that an essential step I shouldn’t have skipped? Or what else could have gone wrong in my case?

Because of this error:

No such file or directory: ‘/mnt/Storage_100101_z2cl/iocage/.plugins/github_com_freenas_iocage-ix-plugins_git/plex.json’

You need to make that file exist… so look for it under it’s new name and rename it (or copy it)

Since upgrade to FreeNAS 12.x it looks the json is changed to: plexmediaserver-plexpass.json

to the old one….
plex.json

  • #9

Because of this error:

You need to make that file exist… so look for it under it’s new name and rename it (or copy it)

to the old one….
plex.json

Ah, thanks, sretalla. I was able to copy the file and upgrade the Plex plugin.
Contrary to TW1920 I don’t get a message that pkg isn’t installed, nor did I encounter the certificate revoking. But I did run into another problem. The web interface is unavailable (server not found). I tried to restart the plugin, but that didn’t work. Nor did restarting the server help. But the plugin status is listed as ‘up’. Release now says: 12.2-RELEASE-p11 but Version still is being displayed as: N/A.
How do I troubleshoot this?

sretalla


  • #10

After the jail version is upgraded, you probably need to do a pkg upgrade inside the jail and say yes to a bunch of things.

  • #11

Sorry; no luck this time. Tried to use pkg upgrade but I didn’t have to say yes to anything; just got: «All repositories are up to date.» and «Your packages are up to date.» Sounds good, but it didn’t solve the problem.

Should I reinstall the plugin? Because the installed instances is 0, surprisingly. So somehow my installed version is no longer recognized as the official plugin.

  • Schermafbeelding 2021-11-16 om 19.31.16.png

    Schermafbeelding 2021-11-16 om 19.31.16.png

    306.6 KB · Views: 82

  • #1

I have recently upgraded my TrueNAS from beta version to TrueNAS-12.0-RC1. Upon this I have tried to update my Plug-in (PLEX) and now receive the following upgrade error, «Error: Major ABI change detected, please run ‘upgrade’ instead.»

I have opened the shell and upgrade PLEX, but it does not seem to work. Can anyone tell me how to UPGRADE the addin’s within TrueNAS?

My current version of PLEX shows:
Version:
1.20.1.3252
Plugin:
plexmediaserver
Release:
11.3-RELEASE-p13
Collection:

  • #5

I think its a matter of updating the Release of 11.3-p13 for the plug in to v12…but im not sure how to do that. Ive googled for answers but have not found anything.

  • #6

I posted the same question on the 12 forum… @Jurgen Segaert replied:

Upgrading is done from the shell, something like iocage upgrade jailname -r 12.1-RELEASE as per the manual

  • #7

I posted the same question on the 12 forum… @Jurgen Segaert replied:

Upgrading is done from the shell, something like iocage upgrade jailname -r 12.1-RELEASE as per the manual

Plex upgrade.png

When I update a TrueNAS/FreeNAS plugin jail, I encounter the following error,

Updating Plugin

Error: Major ABI change detected, please run 'upgrade' instead. 

The screen shot is below

After some research on the truenas forum, I have gotten a sense what’s going on. 

  1. First, let’s be sure what TrueNAS/FreeNAS release that we are on by issuing the uname -r command, e.g.,
    
    TrueNAS $ uanme -r
    12.2-RELEASE-p10
    TrueNAS $
        
  2. Second, let’s list the plugins. For this, we need to open a TrueNAS/FreeNAS shell, and issue iocage list, e.g.,
    
    TrueNAS $ iocage list
    +------+-----------------+-------+--------------+--------------+
    | JID  |      NAME       | STATE |   RELEASE    |    IP4       |
    +======+=================+=======+==============+==============+
    | 4    | calibre         | up    | 11.2-RELEASE | DHCP         |
    +------+-----------------+-------+--------------+--------------+
    | 5    | nextcloud       | up    | 12.2-RELEASE | 198.51.100.1 |
    +------+-----------------+-------+--------------+--------------+
    | 7    | plexmediaserver | up    | 12.2-RELEASE | DHCP         |
    +------+-----------------+-------+--------------+--------------+
    
    TrueNAS $
      

    where we can see that the jail of plugin calibrehas a different system release number.

  3. Then, upgrade the jail’s release using the iocage upgrade command, e.g.,
    
    TrueNAS $ iocage upgrade calibre -r 12.2-RELEASE
        ...
    TrueNAS $
    
# Copyright (c) 2014-2019, iocage # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted providing that the following conditions # are met: # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE AUTHOR «AS IS» AND ANY EXPRESS OR # IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, # STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING # IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. «»»iocage plugin module»»» import collections import concurrent.futures import contextlib import datetime import distutils.dir_util import json import logging import os import git import pathlib import re import shutil import subprocess as su import requests import tarfile import tempfile import threading import urllib.parse import uuid import iocage_lib.ioc_common import iocage_lib.ioc_create import iocage_lib.ioc_destroy import iocage_lib.ioc_exec import iocage_lib.ioc_list import iocage_lib.ioc_json import iocage_lib.ioc_start import iocage_lib.ioc_stop import iocage_lib.ioc_upgrade import iocage_lib.ioc_exceptions import texttable from iocage_lib.cache import cache from iocage_lib.dataset import Dataset GIT_LOCK = threading.Lock() RE_PLUGIN_VERSION = re.compile(r'»path»:»([/.+,dw-]*).txz»‘) class IOCPlugin(object): «»» This is responsible for the general life cycle of a plugin jail. This includes creation, updating and upgrading. «»» PLUGIN_VERSION = ‘2’ DEFAULT_PROPS = { ‘vnet’: 1, ‘boot’: 1 } def __init__( self, release=None, jail=None, plugin=None, branch=None, keep_jail_on_failure=False, callback=None, silent=False, **kwargs ): self.pool = iocage_lib.ioc_json.IOCJson().json_get_value(«pool») self.iocroot = iocage_lib.ioc_json.IOCJson( self.pool).json_get_value(«iocroot») self.release = release if os.path.exists(plugin or »): self.plugin_json_path = plugin plugin = plugin.rsplit(‘/’, 1)[1].rstrip(‘.json’) if self.plugin_json_path == jail: # If user specified a complete path to plugin json file # jail would be having the same value. We ensure that we don’t # do that here. jail = f’{plugin}_{str(uuid.uuid4())[:4]} else: self.plugin_json_path = None self.plugin = plugin self.jail = jail self.http = kwargs.pop(«http», True) self.hardened = kwargs.pop(«hardened», False) self.date = datetime.datetime.utcnow().strftime(«%F») self.branch = branch self.silent = silent self.callback = callback self.keep_jail_on_failure = keep_jail_on_failure self.thickconfig = kwargs.pop(‘thickconfig’, False) self.log = logging.getLogger(‘iocage’) # If we have a jail which exists for this plugin, we will like to # enforce the plugin to respect the github repository it was # created from for updates/upgrades etc. If for some reason, this # is not desired, the user is free to change it via «set» manually # on his own. # TODO: For a lack of ability to do this efficiently/correctly here, # the above should be enforced by the caller of IOCPlugin self.git_repository = kwargs.get( ‘git_repository’ ) or ‘https://github.com/freenas/iocage-ix-plugins.git’ self.git_destination = kwargs.get(‘git_destination’) if not self.git_destination: # If not provided, we use git repository uri and split on scheme # and convert slashes/dot to underscore to guarantee uniqueness # i.e github_com_freenas_iocage-ix-plugins_git self.git_destination = os.path.join( self.iocroot, ‘.plugins’, self.git_repository.split( ‘://’, 1)[1].replace(‘/’, ‘_’).replace(‘.’, ‘_’) ) if self.branch is None and not self.hardened: r = cache.freebsd_version self.branch = f’{r}-RELEASE’ if ‘.’ in r else f’{r}.0-RELEASE’ elif self.branch is None and self.hardened: # Backwards compat self.branch = ‘master’ def pull_clone_git_repo(self, depth=None): self._clone_repo( self.branch, self.git_repository, self.git_destination, depth, self.callback ) @staticmethod def fetch_plugin_packagesites(package_sites): def download_parse_packagesite(packagesite_url): package_site_data = {} try: with tempfile.TemporaryDirectory() as tmpdir: packagesite_txz_path = os.path.join(tmpdir, ‘packagesite.txz’) with requests.get( f’{packagesite_url}/packagesite.txz’, stream=True, timeout=300 ) as r: r.raise_for_status() with open(packagesite_txz_path, ‘wb’) as f: shutil.copyfileobj(r.raw, f) with tarfile.open(packagesite_txz_path) as p_file: p_file.extractall(path=tmpdir) packagesite_path = os.path.join(tmpdir, ‘packagesite.yaml’) if not os.path.exists(packagesite_path): raise FileNotFoundError(f’{packagesite_path} not found’) with open(packagesite_path, ‘r’) as f: for line in f.read().split(n): searched = RE_PLUGIN_VERSION.findall(line) if not searched: continue name = searched[0].rsplit(‘/’, 1)[1] package_site_data[ name.rsplit(‘-‘, 1)[0] ] = iocage_lib.ioc_common.parse_package_name(name) except Exception: pass return packagesite_url, package_site_data plugin_packagesite_mapping = {} package_sites = set([ url.rstrip(‘/’) for url in package_sites ]) with concurrent.futures.ThreadPoolExecutor() as exc: results = exc.map( download_parse_packagesite, package_sites ) for result in results: plugin_packagesite_mapping[result[0]] = result[1] return plugin_packagesite_mapping @staticmethod def fetch_plugin_versions_from_plugin_index(plugins_index): plugin_packagesite_mapping = IOCPlugin.fetch_plugin_packagesites([ v[‘packagesite’] for v in plugins_index.values() ]) version_dict = {} for plugin in plugins_index: plugin_dict = plugins_index[plugin] packagesite = plugin_dict[‘packagesite’] primary_package = plugin_dict.get(‘primary_pkg’) or plugin packagesite = packagesite.rstrip(‘/’) plugin_pkgs = plugin_packagesite_mapping[packagesite] try: version_data = plugin_pkgs[primary_package] except KeyError: plugin_dict.update({ k: ‘N/A’ for k in (‘revision’, ‘version’, ‘epoch’) }) else: plugin_dict.update(version_data) version_dict[plugin] = plugin_dict return version_dict @staticmethod def retrieve_plugin_index_data(plugin_index_path, expand_abi=True): plugin_index = {} index_path = os.path.join(plugin_index_path, ‘INDEX’) if not os.path.exists(index_path): return plugin_index with open(index_path, ‘r’) as f: index = json.loads(f.read()) for plugin in index: plugin_manifest_path = os.path.join( plugin_index_path, index[plugin][‘MANIFEST’] ) if not os.path.exists(plugin_manifest_path): continue with open(plugin_manifest_path, ‘r’) as f: plugin_manifest_data = json.loads(f.read()) if not any(plugin_manifest_data.get(k) for k in (‘release’, ‘packagesite’)): continue if expand_abi and ‘${ABI}’ in plugin_manifest_data[‘packagesite’]: plugin_manifest_data[‘packagesite’] = IOCPlugin.expand_abi_with_specified_release( plugin_manifest_data[‘packagesite’], plugin_manifest_data[‘release’] ) plugin_index[plugin] = { ‘primary_pkg’: index[plugin].get(‘primary_pkg’), ‘category’: index[plugin].get(‘category’), **plugin_manifest_data } return plugin_index @staticmethod def expand_abi_with_specified_release(packagesite, release): return packagesite.replace( ‘${ABI}’, f’FreeBSD:{release.split(«-«)[0].split(«.»)[0]}:amd64′ ) def fetch_plugin_versions(self): self.pull_clone_git_repo() plugin_index = self.retrieve_plugin_index_data(self.git_destination) return self.fetch_plugin_versions_from_plugin_index(plugin_index) def retrieve_plugin_json(self): if not self.plugin_json_path: _json = os.path.join(self.git_destination, f’{self.plugin}.json’) if not os.path.exists(self.git_destination): self.pull_clone_git_repo() else: _json = self.plugin_json_path self.log.debug(f’Plugin json file path: {_json}) try: with open(_json, ‘r’) as j: conf = json.load(j) except FileNotFoundError: iocage_lib.ioc_common.logit( { ‘level’: ‘EXCEPTION’, ‘message’: f’{_json} was not found!’ }, _callback=self.callback ) except json.decoder.JSONDecodeError: iocage_lib.ioc_common.logit( { ‘level’: ‘EXCEPTION’, ‘message’: ‘Invalid JSON file supplied, please supply a ‘ ‘correctly formatted JSON file.’ }, _callback=self.callback ) return conf def fetch_plugin(self, props, num, accept_license): «»»Helper to fetch plugins»»» plugins = self.fetch_plugin_index(props, index_only=True) conf = self.retrieve_plugin_json() iocage_lib.ioc_common.validate_plugin_manifest(conf, self.callback, self.silent) if self.hardened: conf[‘release’] = conf[‘release’].replace(«-RELEASE», «-STABLE») conf[‘release’] = re.sub(r»Ww.», «-«, conf[‘release’]) self.release = conf[‘release’] props, pkg = self.__fetch_plugin_props__(conf, props, num) self.__fetch_plugin_inform__(conf, num, plugins, accept_license) location = {self.iocroot}/jails/{self.jail}« try: jaildir, _conf, repo_dir = self.__fetch_plugin_create__(props) # As soon as we create the jail, we should write the plugin manifest to jail directory # This is done to ensure that subsequent starts of the jail make use of the plugin # manifest as required status, jid = iocage_lib.ioc_list.IOCList().list_get_jid(self.jail) if status: iocage_lib.ioc_stop.IOCStop( self.jail, jaildir, silent=True, force=True, callback=self.callback ) with open(os.path.join(jaildir, f’{self.plugin}.json’), ‘w’) as f: f.write(json.dumps(conf, indent=4, sort_keys=True)) self.__fetch_plugin_install_packages__( jaildir, conf, pkg, props, repo_dir ) self.__fetch_plugin_post_install__(conf, _conf, jaildir) except BaseException as e: if not self.keep_jail_on_failure: msg = f’{self.jail} had a failuren f’Exception: {e.__class__.__name__} f’Message: {str(e)}n f’Partial plugin destroyed’ iocage_lib.ioc_destroy.IOCDestroy().destroy_jail(location) iocage_lib.ioc_common.logit({ ‘level’: ‘EXCEPTION’, ‘message’: msg }, _callback=self.callback, silent=self.silent) raise def __fetch_plugin_inform__(self, conf, num, plugins, accept_license): «»»Logs the pertinent information before fetching a plugin»»» if num <= 1: iocage_lib.ioc_common.logit( { «level»: «INFO», «message»: f»Plugin: {conf[‘name’]}« }, _callback=self.callback, silent=self.silent) iocage_lib.ioc_common.logit( { «level»: «INFO», «message»: f» Official Plugin: {conf.get(‘official’, False)}« }, _callback=self.callback, silent=self.silent) iocage_lib.ioc_common.logit( { «level»: «INFO», «message»: f» Using RELEASE: {conf[‘release’]}« }, _callback=self.callback, silent=self.silent) iocage_lib.ioc_common.logit( { «level»: «INFO», «message»: f» Using Branch: {self.branch}« }, _callback=self.callback, silent=self.silent) iocage_lib.ioc_common.logit( { «level»: «INFO», «message»: f» Post-install Artifact: {conf[‘artifact’]}« }, _callback=self.callback, silent=self.silent) iocage_lib.ioc_common.logit( { «level»: «INFO», «message»: » These pkgs will be installed:» }, _callback=self.callback, silent=self.silent) for pkg in conf[«pkgs»]: iocage_lib.ioc_common.logit( { «level»: «INFO», «message»: f» — {pkg}« }, _callback=self.callback, silent=self.silent) # Name would be convenient, but it doesn’t always gel with the # JSON’s title, pkg always does. try: license = plugins[pkg.split(«/», 1)[1]].get(«license», False) except UnboundLocalError: license = plugins.get( conf[«name»].lower().split(«/», 1)[1], conf ).get(«license», False) except KeyError: # quassel-core is one that does this. license = plugins.get( conf[«name»].strip(«-«).lower().split(«/», 1)[1], conf ).get(«license», False) if license and not accept_license: license_text = requests.get(license) iocage_lib.ioc_common.logit( { «level»: «WARNING», «message»: » This plugin requires accepting a license « «to proceed:» }, _callback=self.callback, silent=self.silent) iocage_lib.ioc_common.logit( { «level»: «VERBOSE», «message»: {license_text.text}« }, _callback=self.callback, silent=self.silent) agree = input(«Do you agree? (y/N) «) if agree.lower() != «y»: iocage_lib.ioc_common.logit( { «level»: «EXCEPTION», «message»: «You must accept the license to continue!» }, _callback=self.callback) def __fetch_plugin_props__(self, conf, props, num): «»»Generates the list of properties that a user and the JSON supply»»» self.release = conf[«release»] pkg_repos = conf[«fingerprints»] freebsd_version = {self.iocroot}/releases/{conf[‘release’]}« «/root/bin/freebsd-version» json_props = conf.get(«properties», {}) truthy_inverse = iocage_lib.ioc_common.truthy_inverse_values() props = {p.split(‘=’)[0]: p.split(‘=’)[1] for p in list(props)} network_props = { ‘nat’: truthy_inverse, ‘dhcp’: truthy_inverse, ‘ip4_addr’: (‘none’,), ‘ip6_addr=’: (‘none’,) } for p, v in json_props.items(): # The JSON properties are going to be treated as user entered # ones on the command line. If the users prop exists on the # command line, we will skip the JSON one. if p not in props: if p in network_props and v not in network_props[p]: # This means that «p» is enabled in the plugin manifest # We should now ensure that we don’t have any other # connectivity option enabled network_props.pop(p) if any( nk in props and props[nk] not in nv for nk, nv in network_props.items() ): # This means that some other network option has # been specified which is enabled and we don’t want # to add the plugin manifest default continue props[p] = v if not os.path.isdir({self.iocroot}/releases/{self.release}«): iocage_lib.ioc_common.check_release_newer( self.release, self.callback, self.silent, major_only=True) self.__fetch_release__(self.release) if conf[«release»][:4].endswith(«-«): # 9.3-RELEASE and under don’t actually have this binary. release = conf[«release»] else: iocage_lib.ioc_common.check_release_newer( self.release, self.callback, self.silent, major_only=True) try: with open( freebsd_version, mode=‘r’, encoding=‘utf-8’ ) as r: for line in r: if line.startswith(«USERLAND_VERSION»): release = line.rstrip().partition(«=»)[2].strip( ‘»‘) except FileNotFoundError: iocage_lib.ioc_common.logit( { «level»: «WARNING», «message»: f»Release {self.release} missing, « f»will attempt to fetch it.» }, _callback=self.callback, silent=self.silent) self.__fetch_release__(self.release) # We still want this. with open( freebsd_version, mode=‘r’, encoding=‘utf-8’ ) as r: for line in r: if line.startswith(«USERLAND_VERSION»): release = line.rstrip().partition(«=»)[2].strip( ‘»‘) # We set our properties that we need, and then iterate over the user # supplied properties replacing ours. create_props = [f’release={release}] + [ f’{k}={v} for k, v in {**self.DEFAULT_PROPS, **props}.items() ] if all( props.get(k, ‘none’) == ‘none’ for k in (‘ip4_addr’, ‘ip6_addr’) ) and not iocage_lib.ioc_common.boolean_prop_exists( create_props, [‘dhcp’, ‘nat’, ‘ip_hostname’] ): iocage_lib.ioc_common.logit( { ‘level’: ‘EXCEPTION’, ‘message’: ‘Network connectivity is required to fetch a ‘ ‘plugin. Please enable dhcp/nat or supply’ ‘ a valid ip address.’ }, _callback=self.callback, silent=self.silent) # These properties are not user configurable for prop in ( f’type=pluginv{self.PLUGIN_VERSION}, f’plugin_name={self.plugin}, f’plugin_repository={self.git_repository}, ): create_props.append(prop) return create_props, pkg_repos def __fetch_plugin_create__(self, create_props): «»»Creates the plugin with the provided properties»»» iocage_lib.ioc_create.IOCCreate( self.release, create_props, 0, silent=True, basejail=True, uuid=self.jail, plugin=True, thickconfig=self.thickconfig, callback=self.callback ).create_jail() jaildir = {self.iocroot}/jails/{self.jail}« repo_dir = {jaildir}/root/usr/local/etc/pkg/repos» path = {self.pool}/iocage/jails/{self.jail}« _conf = iocage_lib.ioc_json.IOCJson(jaildir).json_get_value(‘all’) # We do these tests again as the user could supply a malformed IP to # fetch that bypasses the more naive check in cli/fetch auto_configs = _conf[‘dhcp’] or _conf[‘ip_hostname’] or _conf[‘nat’] if _conf[«ip4_addr»] == «none» and _conf[«ip6_addr»] == «none» and not auto_configs: iocage_lib.ioc_common.logit( { «level»: «ERROR», «message»: «nAn IP address is needed to fetch a « «plugin!n« }, _callback=self.callback, silent=self.silent) iocage_lib.ioc_destroy.IOCDestroy().destroy_jail(path) iocage_lib.ioc_common.logit( { «level»: «EXCEPTION», «message»: «Destroyed partial plugin.» }, _callback=self.callback) return jaildir, _conf, repo_dir def __fetch_plugin_install_packages__(self, jaildir, conf, pkg_repos, create_props, repo_dir): «»»Attempts to start the jail and install the packages»»» kmods = conf.get(«kmods», {}) secure = True if «https://» in conf[«packagesite»] else False for kmod in kmods: self.log.debug(f’Loading {kmod}) try: su.check_call( [«kldload», «-n», kmod], stdout=su.PIPE, stderr=su.PIPE) except su.CalledProcessError: iocage_lib.ioc_common.logit( { «level»: «EXCEPTION», «message»: «Module not found!» }, _callback=self.callback) if secure: # Certificate verification iocage_lib.ioc_common.logit( { «level»: «INFO», «message»: «Secure packagesite detected, installing « «ca_root_nss package.» }, _callback=self.callback, silent=self.silent) err = iocage_lib.ioc_create.IOCCreate( self.release, create_props, 0, pkglist=[«ca_root_nss»], silent=True, callback=self.callback ).create_install_packages( self.jail, jaildir ) if err: iocage_lib.ioc_common.logit( { «level»: «EXCEPTION», «message»: «pkg error, please try non-secure packagesite.» }, _callback=self.callback) freebsd_conf = «»» FreeBSD: { enabled: no } «»» try: os.makedirs(repo_dir, 0o755) except OSError: # It exists, that’s fine. pass with open({jaildir}/root/usr/local/etc/pkg/repos/FreeBSD.conf», «w») as f_conf: f_conf.write(freebsd_conf) for repo in pkg_repos: repo_name = repo repo = pkg_repos[repo] f_dir = {jaildir}/root/usr/local/etc/pkg/fingerprints/» {repo_name}/trusted» r_dir = {jaildir}/root/usr/local/etc/pkg/fingerprints/» {repo_name}/revoked» repo_conf = «»» {reponame}: {{ url: «{packagesite}», signature_type: «fingerprints», fingerprints: «/usr/local/etc/pkg/fingerprints/{reponame}», enabled: true }} «»» try: os.makedirs(f_dir, 0o755) os.makedirs(r_dir, 0o755) except OSError: iocage_lib.ioc_common.logit( { «level»: «ERROR», «message»: f»Repo: {repo_name} already exists, skipping!» }, _callback=self.callback, silent=self.silent) r_file = {repo_dir}/{repo_name}.conf» with open(r_file, «w») as r_conf: r_conf.write( repo_conf.format( reponame=repo_name, packagesite=conf[«packagesite»])) f_file = {f_dir}/{repo_name}« for r in repo: finger_conf = «»» function: {function} fingerprint: {fingerprint} «»» with open(f_file, «w») as f_conf: f_conf.write( finger_conf.format( function=r[«function»], fingerprint=r[«fingerprint»])) err = iocage_lib.ioc_create.IOCCreate( self.release, create_props, 0, pkglist=conf[«pkgs»], silent=True, plugin=True, callback=self.callback ).create_install_packages( self.jail, jaildir, repo=conf[«packagesite»] ) if err: iocage_lib.ioc_common.logit( { «level»: «EXCEPTION», «message»: npkg error:n{err}n« «nRefusing to fetch artifact and run post_install.sh!» }, _callback=self.callback) def __fetch_plugin_post_install__(self, conf, _conf, jaildir): «»»Fetches the users artifact and runs the post install»»» status, jid = iocage_lib.ioc_list.IOCList().list_get_jid(self.jail) if not status: iocage_lib.ioc_start.IOCStart(self.jail, jaildir, silent=True) ip4 = _conf[‘ip4_addr’] ip6 = _conf[‘ip6_addr’] ip = None if ip6 != ‘none’: ip = ‘,’.join([ v.split(‘|’)[1].split(‘/’)[0] for v in ip6.split(‘,’) if ‘accept_rtadv’ not in v.lower() ]) if not ip and ip4 != ‘none’: ip = ‘,’.join([ v.split(‘|’)[1].split(‘/’)[0] for v in ip4.split(‘,’) if ‘dhcp’ not in v.lower() ]) if not ip: if _conf[‘vnet’]: interface = _conf[‘interfaces’].split(‘,’)[0].split(‘:’)[0] if interface == ‘vnet0’: # Jails use epairNb by default inside interface = f’{interface.replace(«vnet», «epair»)}b’ ip4_cmd = [ ‘jexec’, f’ioc-{self.jail.replace(«.», «_»)}, ‘ifconfig’, interface, ‘inet’ ] out = su.check_output(ip4_cmd).decode() ip = f’{out.splitlines()[2].split()[1]} else: ip = json.loads( su.run([ ‘jls’, ‘-j’, f’ioc-{self.jail.replace(«.», «_»)}, ‘—libxo’, ‘json’ ], stdout=su.PIPE).stdout )[‘jail-information’][‘jail’][0][‘ipv4’] self.log.debug(f’IP for {self.plugin}{self.jail}: {ip}.’) os.environ[‘IOCAGE_PLUGIN_IP’] = ip plugin_env = { **{ k: os.environ.get(k) for k in [‘http_proxy’, ‘https_proxy’] if os.environ.get(k) }, ‘IOCAGE_PLUGIN_IP’: ip } # We need to pipe from tar to the root of the jail. if conf[«artifact»]: iocage_lib.ioc_common.logit( { «level»: «INFO», «message»: «nFetching artifact… « }, _callback=self.callback, silent=self.silent) self.__update_pull_plugin_artifact__(conf) try: shutil.copy({jaildir}/plugin/post_install.sh», {jaildir}/root/root») iocage_lib.ioc_common.logit( { «level»: «INFO», «message»: «nRunning post_install.sh» }, _callback=self.callback, silent=self.silent) command = [«/root/post_install.sh»] try: with iocage_lib.ioc_exec.IOCExec( command, jaildir, uuid=self.jail, plugin=True, skip=True, callback=self.callback, su_env=plugin_env ) as _exec: iocage_lib.ioc_common.consume_and_log( _exec, callback=self.callback ) except iocage_lib.ioc_exceptions.CommandFailed as e: message = b’ ‘.join(e.message[10:]).decode().rstrip() iocage_lib.ioc_common.logit( { ‘level’: ‘EXCEPTION’, ‘message’: f’Last 10 lines:n{message} }, _callback=self.callback) ui_json = {jaildir}/plugin/ui.json» try: with open(ui_json, «r») as u: ui_data = json.load(u) admin_portal = ui_data.get(‘adminportal’, None) doc_url = ui_data.get(‘docurl’, None) if admin_portal: admin_portal = ‘,’.join( iocage_lib.ioc_common.retrieve_admin_portals( _conf, True, admin_portal ) ) try: ph = ui_data[ ‘adminportal_placeholders’ ].items() for placeholder, prop in ph: admin_portal = admin_portal.replace( placeholder, iocage_lib.ioc_json.IOCJson( jaildir).json_plugin_get_value( prop.split(‘.’)) ) except KeyError: pass iocage_lib.ioc_common.logit( { ‘level’: ‘INFO’, ‘message’: nAdmin Portal:n f’{admin_portal} }, _callback=self.callback, silent=self.silent) if doc_url is not None: iocage_lib.ioc_common.logit( { ‘level’: ‘INFO’, ‘message’: f’nDoc URL:n{doc_url} }, _callback=self.callback, silent=self.silent) except FileNotFoundError: # They just didn’t set a admin portal or doc url. pass except FileNotFoundError: pass def fetch_plugin_index( self, props, _list=False, list_header=False, list_long=False, accept_license=False, icon=False, official=False, index_only=False ): self.pull_clone_git_repo() index_path = os.path.join(self.git_destination, ‘INDEX’) if not os.path.exists(index_path): # Gracefully handle index not existing bit iocage_lib.ioc_common.logit( { ‘level’: ‘EXCEPTION’, ‘message’: ‘Unable to retrieve INDEX of ‘ f’{self.git_destination} at ‘ f’{index_path}.’ }, _callback=self.callback, silent=self.silent ) else: with open(index_path, ‘r’) as plugins: plugins = json.load(plugins) if index_only: return plugins plugins_ordered_dict = collections.OrderedDict( sorted({ k: {‘name’: v[‘name’], ‘description’: v[‘description’]} for k, v in plugins.items() if not (official and not v.get(‘official’, False)) }.items()) ) if self.plugin is None and not _list: for i, p in enumerate(plugins_ordered_dict.items()): k, v = p iocage_lib.ioc_common.logit( { ‘level’: ‘INFO’, ‘message’: f'[{i}] {v[«name»]}{v[«description»]} ({k})’ }, _callback=self.callback, silent=self.silent ) if _list: plugin_list = [] for k, v in plugins_ordered_dict.items(): plugin_dict = { ‘name’: v[‘name’], ‘description’: v[‘description’], ‘plugin’: k, } if not list_header: plugin_dict.update({ ‘license’: plugins[k].get(‘license’, »), ‘official’: plugins[k].get(‘official’, False), ‘category’: plugins[k].get(‘category’, None), }) if icon: plugin_dict[‘icon’] = plugins[k].get(‘icon’, None) plugin_list.append(plugin_dict) if not list_header: return plugin_list else: if list_long: table = texttable.Texttable(max_width=0) else: table = texttable.Texttable(max_width=80) list_header = [«NAME», «DESCRIPTION», «PKG»] if icon: list_header += [«ICON»] plugin_list = [ [p[‘name’], p[‘description’], p[‘plugin’]] + ( [p[‘icon’]] if icon else [] ) for p in plugin_list ] plugin_list.insert(0, list_header) table.add_rows(plugin_list) return table.draw() if self.plugin is None: self.plugin = input(«nType the number of the desired» » pluginnPress [Enter] or type EXIT to» » quit: «) self.plugin = self.__fetch_validate_plugin__( self.plugin.lower(), plugins_ordered_dict ) self.jail = f’{self.plugin}_{str(uuid.uuid4())[:4]} # We now run the fetch the user requested self.fetch_plugin(props, 0, accept_license) def __fetch_validate_plugin__(self, plugin, plugins): «»» Checks if the user supplied an index number and returns the plugin. If they gave us a plugin name, we make sure that exists in the list at all. «»» _plugin = plugin # Gets lost in the enumeration if no match is found. if plugin.lower() == «exit»: exit() if plugin.isdigit(): try: plugin = list(plugins.items())[int(plugin)][0] except IndexError: iocage_lib.ioc_common.logit( { «level»: «EXCEPTION», «message»: f»Plugin: {_plugin} not in list!» }, _callback=self.callback) except ValueError: exit() else: if plugin not in plugins: for k, v in plugins.items(): if plugin == v[‘name’]: plugin = k break else: iocage_lib.ioc_common.logit( { ‘level’: ‘EXCEPTION’, ‘message’: f’Plugin: {_plugin} not available.’ }, _callback=self.callback ) return plugin def __run_hook_script__(self, script_path): # If the hook script has a service command, we want it to # succeed. This is essentially a soft jail restart. self.stop_rc() path = {self.iocroot}/jails/{self.jail}« jail_path = os.path.join(self.iocroot, ‘jails’, self.jail) new_script_path = os.path.join(jail_path, ‘root/tmp’) shutil.copy(script_path, new_script_path) script_path = os.path.join( new_script_path, script_path.split(‘/’)[1] ) try: with iocage_lib.ioc_exec.IOCExec( [‘sh’, os.path.join(‘/tmp’, script_path.split(‘/’)[1])], path, uuid=self.jail, plugin=True, skip=True, callback=self.callback ) as _exec: iocage_lib.ioc_common.consume_and_log( _exec, callback=self.callback, log=not self.silent ) except iocage_lib.ioc_exceptions.CommandFailed as e: iocage_lib.ioc_common.logit( { ‘level’: ‘EXCEPTION’, ‘message’: b’n.join(e.message).decode() }, _callback=self.callback, silent=self.silent ) else: self.stop_rc() self.start_rc() def update(self, jid): iocage_lib.ioc_common.logit( { «level»: «INFO», «message»: f»Snapshotting {self.jail}… « }, _callback=self.callback, silent=self.silent) try: self.__snapshot_jail__(name=‘update’) except iocage_lib.ioc_exceptions.Exists: # User may have run update already (so clean) or they created this # snapshot purposely, this is OK pass iocage_lib.ioc_common.logit( { «level»: «INFO», «message»: «Updating plugin INDEX… « }, _callback=self.callback, silent=self.silent) self.pull_clone_git_repo() plugin_conf = self._load_plugin_json() self.__check_manifest__(plugin_conf, upgrade=False) if plugin_conf[‘artifact’]: iocage_lib.ioc_common.logit( { ‘level’: ‘INFO’, ‘message’: ‘Updating plugin artifact… ‘ }, _callback=self.callback, silent=self.silent ) self.__update_pull_plugin_artifact__(plugin_conf) pre_update_hook = os.path.join( self.iocroot, ‘jails’, self.jail, ‘plugin/pre_update.sh’ ) if os.path.exists(pre_update_hook): iocage_lib.ioc_common.logit( { ‘level’: ‘INFO’, ‘message’: ‘Running pre_update.sh… ‘ }, _callback=self.callback, silent=self.silent ) self.__run_hook_script__(pre_update_hook) iocage_lib.ioc_common.logit( { «level»: «INFO», «message»: «Removing old pkgs… « }, _callback=self.callback, silent=self.silent) self.__update_pkg_remove__(jid) iocage_lib.ioc_common.logit( { «level»: «INFO», «message»: «Installing new pkgs… « }, _callback=self.callback, silent=self.silent) self.__update_pkg_install__(plugin_conf) if plugin_conf[«artifact»]: # We need to do this again to ensure that if some files # were removed when we removed pkgs and the overlay directory # is supposed to bring them back, this does that self.__update_pull_plugin_artifact__(plugin_conf) post_update_hook = os.path.join( self.iocroot, ‘jails’, self.jail, ‘plugin/post_update.sh’ ) if os.path.exists(post_update_hook): iocage_lib.ioc_common.logit( { ‘level’: ‘INFO’, ‘message’: ‘Running post_update.sh… ‘ }, _callback=self.callback, silent=self.silent ) self.__run_hook_script__(post_update_hook) self.__remove_snapshot__(name=«update») def __update_pull_plugin_artifact__(self, plugin_conf): «»»Pull the latest artifact to be sure we’re up to date»»» path = {self.iocroot}/jails/{self.jail}« shutil.rmtree({path}/plugin», ignore_errors=True) uri = urllib.parse.urlparse(plugin_conf[‘artifact’]) if uri.scheme == ‘file’: artifact_path = urllib.parse.unquote(uri.path) if not os.path.exists(artifact_path): iocage_lib.ioc_common.logit( { ‘level’: ‘EXCEPTION’, ‘message’: f’{artifact_path} does not exist!’ }, _callback=self.callback, silent=self.silent ) distutils.dir_util.copy_tree( artifact_path, os.path.join(path, ‘plugin’) ) else: self._clone_repo( self.branch, plugin_conf[‘artifact’], f’{path}/plugin’, callback=self.callback ) if os.path.isdir({path}/plugin/overlay/»): try: # Quickfix for distutils cache bug making re-installed # plugins with same name fail to copy the overlay folder distutils.dir_util._path_created = {} distutils.dir_util.copy_tree( {path}/plugin/overlay/», {path}/root», preserve_symlinks=True) except distutils.errors.DistutilsFileError as e: # Copy tree should succeed if the overlay folder exists iocage_lib.ioc_common.logit( { ‘level’: ‘EXCEPTION’, ‘message’: f’Error during overlay copy: {str(e)} }, _callback=self.callback, silent=self.silent ) def __update_pkg_remove__(self, jid): «»»Remove all pkgs from the plugin»»» try: with iocage_lib.ioc_exec.IOCExec( command=[‘pkg’, ‘-j’, jid, ‘delete’, ‘-a’, ‘-f’, ‘-y’], path=f’{self.iocroot}/jails/{self.jail}, uuid=self.jail, callback=self.callback, unjailed=True ) as _exec: iocage_lib.ioc_common.consume_and_log( _exec, callback=self.callback, log=not(self.silent) ) except iocage_lib.ioc_exceptions.CommandFailed as e: self.__rollback_jail__(name=«update») final_msg = «PKG error, update failed! Rolling back snapshot.n« iocage_lib.ioc_common.logit( { «level»: «ERROR», «message»: b’n.join(e.message).decode() }, _callback=self.callback, silent=self.silent) iocage_lib.ioc_common.logit( { «level»: «EXCEPTION», «message»: final_msg }, _callback=self.callback) def __update_pkg_install__(self, plugin_conf): «»»Installs all pkgs listed in the plugins configuration»»» path = {self.iocroot}/jails/{self.jail}« try: self.__fetch_plugin_install_packages__( path, plugin_conf, plugin_conf[‘fingerprints’], [], os.path.join(path, ‘root/usr/local/etc/pkg/repos’) ) except (Exception, SystemExit): iocage_lib.ioc_common.logit( { ‘level’: ‘ERROR’, ‘message’: ‘PKG error, update failed! ‘ ‘Rolling back snapshot.n }, _callback=self.callback ) self.__rollback_jail__(name=‘update’) raise def upgrade(self, jid): iocage_lib.ioc_common.logit( { «level»: «INFO», «message»: f»Snapshotting {self.jail}… « }, _callback=self.callback, silent=self.silent) try: self.__snapshot_jail__(name=‘upgrade’) except iocage_lib.ioc_exceptions.Exists: # User may have run upgrade already (so clean) or they created this # snapshot purposely, this is OK pass iocage_lib.ioc_common.logit( { «level»: «INFO», «message»: «Updating plugin INDEX… « }, _callback=self.callback, silent=self.silent) self.pull_clone_git_repo() plugin_conf = self._load_plugin_json() self.__check_manifest__(plugin_conf, upgrade=True) plugin_release = plugin_conf[«release»] iocage_lib.ioc_common.check_release_newer( plugin_release, self.callback, self.silent, major_only=True) # We want the new json to live with the jail plugin_name = self.plugin.rsplit(‘_’, 1)[0] shutil.copy( os.path.join(self.git_destination, f’{plugin_name}.json’), os.path.join( self.iocroot, ‘jails’, self.jail, f’{plugin_name}.json’ ) ) release_p = pathlib.Path({self.iocroot}/releases/{plugin_release}«) if not release_p.exists(): iocage_lib.ioc_common.check_release_newer( plugin_release, self.callback, self.silent) iocage_lib.ioc_common.logit( { «level»: «WARNING», «message»: «New plugin RELEASE missing, fetching now… « }, _callback=self.callback, silent=self.silent) self.__fetch_release__(plugin_release) path = {self.iocroot}/jails/{self.jail}/root» iocage_lib.ioc_common.logit( { «level»: «INFO», «message»: «Running upgrade… « }, _callback=self.callback, silent=self.silent) new_release = iocage_lib.ioc_upgrade.IOCUpgrade( plugin_release, path, silent=True ).upgrade_basejail( snapshot=False, snap_name=f’ioc_plugin_upgrade_{self.date} ) self.update(jid) return new_release def __snapshot_jail__(self, name): «»»Snapshot the plugin»»» # Utilize the nicer API interface for this import iocage_lib.iocage as ioc # Avoids dep issues name = f»ioc_plugin_{name}_{self.date}« ioc.IOCage( jail=self.jail, skip_jails=True, silent=True ).snapshot(name) def __rollback_jail__(self, name): «»»Rollback the plugins snapshot»»» # Utilize the nicer API interface for this import iocage_lib.iocage as ioc # Avoids dep issues name = f»ioc_plugin_{name}_{self.date}« iocage = ioc.IOCage( jail=self.jail, skip_jails=True, silent=True) iocage.stop() iocage.rollback(name) def _plugin_json_file(self): plugin_name = self.plugin.rsplit(‘_’, 1)[0] jail_name = self.jail or plugin_name try: with open( os.path.join( self.iocroot, ‘jails’, jail_name, f’{plugin_name}.json’ ), ‘r’ ) as f: manifest = json.loads(f.read()) except Exception: iocage_lib.ioc_common.logit( { ‘level’: ‘EXCEPTION’, ‘message’: f’Failed retrieving {jail_name} json’ }, _callback=self.callback ) else: return manifest def _load_plugin_json(self): «»»Load the plugins configuration»»» plugin_name = self.plugin.rsplit(‘_’, 1)[0] _json = os.path.join(self.git_destination, f’{plugin_name}.json’) try: with open(_json, «r») as j: _conf = json.load(j) except FileNotFoundError: _conf = self.__find_plugin_json(plugin_name) except json.decoder.JSONDecodeError: iocage_lib.ioc_common.logit( { «level»: «EXCEPTION», «message»: «Invalid JSON file supplied, please supply a « «correctly formatted JSON file.» }, _callback=self.callback) return _conf def __find_plugin_json(self, plugin_name): «»»Matches the name of the local plugin’s json with the INDEX’s»»» _json = f’{self.iocroot}/jails/{self.plugin}/{plugin_name}.json’ try: with open(_json, ‘r’) as j: p_conf = json.load(j) p_name = p_conf[‘name’] except FileNotFoundError: iocage_lib.ioc_common.logit( { ‘level’: ‘EXCEPTION’, ‘message’: f’{_json} was not found!’ }, _callback=self.callback) except json.decoder.JSONDecodeError: iocage_lib.ioc_common.logit( { ‘level’: ‘EXCEPTION’, ‘message’: ‘Invalid JSON file supplied, please supply a ‘ ‘correctly formatted JSON file.’ }, _callback=self.callback) jsons = pathlib.Path(self.git_destination).glob(‘*.json’) for f in jsons: _conf = json.loads(pathlib.Path(f).open(‘r’).read()) if _conf[‘name’] == p_name: return _conf iocage_lib.ioc_common.logit( { ‘level’: ‘EXCEPTION’, ‘message’: f’A plugin manifest matching {p_name} could not ‘ ‘be found!’ }, _callback=self.callback) def __remove_snapshot__(self, name): «»»Removes all matching plugin snapshots»»» conf = iocage_lib.ioc_json.IOCJson( f’{self.iocroot}/jails/{self.jail} ).json_get_value(‘all’) release = conf[‘release’] names = [f’ioc_plugin_{name}_{self.date}, f’ioc_update_{release}] for snap in Dataset( f’{self.pool}/iocage/jails/{self.jail} ).snapshots_recursive(): snap_name = snap.name if snap_name in names: snap.destroy(recursive=False, force=False) def stop_rc(self): iocage_lib.ioc_exec.SilentExec( command=[«/bin/sh», «/etc/rc.shutdown»], path={self.iocroot}/jails/{self.jail}«, uuid=self.jail, callback=self.callback ) def start_rc(self): iocage_lib.ioc_exec.SilentExec( command=[«/bin/sh», «/etc/rc»], path={self.iocroot}/jails/{self.jail}«, uuid=self.jail, callback=self.callback ) def __check_manifest__(self, plugin_conf, upgrade): «»»If the Major ABI changed, they cannot update anymore.»»» jail_conf, write = iocage_lib.ioc_json.IOCJson( location={self.iocroot}/jails/{self.jail}«).json_load() jail_rel = int(jail_conf[«release»].split(«.», 1)[0]) manifest_rel = int(plugin_conf[«release»].split(«.», 1)[0]) manifest_major_minor = float( plugin_conf[«release»].rsplit(«-«, 1)[0].rsplit(«-«, 1)[0]) iocage_lib.ioc_common.check_release_newer( manifest_major_minor, self.callback, self.silent) if not upgrade and jail_rel < manifest_rel: self.__remove_snapshot__(name=«update») iocage_lib.ioc_common.logit( { «level»: «EXCEPTION», «message»: «Major ABI change detected, please run» » ‘upgrade’ instead.» }, _callback=self.callback) def __fetch_release__(self, release): «»»Will call fetch to get the new RELEASE the plugin will rely on»»» fetch_args = {‘release’: release, ‘eol’: False} iocage_lib.iocage.IOCage(silent=self.silent).fetch(**fetch_args) @staticmethod def _verify_git_repo(repo_url, destination): verified = False with contextlib.suppress( git.exc.InvalidGitRepositoryError, git.exc.NoSuchPathError, AttributeError, ): repo = git.Repo(destination) verified = any(u == repo_url for u in repo.remotes.origin.urls) return verified @staticmethod def _clone_repo(ref, repo_url, destination, depth=None, callback=None): «»» This is to replicate the functionality of cloning/pulling a repo «»» with GIT_LOCK: branch = ref try: if os.path.exists( destination ) and not IOCPlugin._verify_git_repo(repo_url, destination): raise git.exc.InvalidGitRepositoryError() # «Pull» repo = git.Repo(destination) origin = repo.remotes.origin ref = ‘master’ if f’origin/{ref} not in repo.refs else ref for command in [ [‘checkout’, ref], [‘pull’] ]: iocage_lib.ioc_exec.SilentExec( [‘git’, ‘-C’, destination] + command, None, unjailed=True, decode=True, su_env={ k: os.environ.get(k) for k in [‘http_proxy’, ‘https_proxy’] if os.environ.get(k) } ) except ( iocage_lib.ioc_exceptions.CommandFailed, git.exc.InvalidGitRepositoryError, git.exc.NoSuchPathError ) as e: basic_msg = ‘Failed to update git repository:’ exception_message = » if isinstance(e, git.exc.NoSuchPathError): f_msg = ‘Cloning git repository’ elif isinstance(e, git.exc.InvalidGitRepositoryError): f_msg = f’{basic_msg} Invalid Git Repository’ else: exception_message = b’ ‘.join( filter(bool, e.message) ).decode() f_msg = f’{basic_msg} f’{exception_message} iocage_lib.ioc_common.logit( { ‘level’: ‘ERROR’, ‘message’: f_msg } ) if exception_message.strip().startswith( ‘fatal: unable to access’ ): # It is possible the user had a bad network and we # would be in this case destroying the plugin repository # which would function okay to at least get the # required data points while listing plugins iocage_lib.ioc_common.logit( { ‘level’: ‘ERROR’, ‘message’: f’Not cloning {repo_url} ‘as git-pull failed due to ‘ ‘network issues.’ } ) return # Clone shutil.rmtree(destination, ignore_errors=True) kwargs = {‘env’: os.environ.copy(), ‘depth’: depth} repo = git.Repo.clone_from( repo_url, destination, **{ k: v for k, v in kwargs.items() if v } ) origin = repo.remotes.origin if not origin.exists(): iocage_lib.ioc_common.logit( { ‘level’: ‘EXCEPTION’, ‘message’: f’Origin: {origin.url} does not exist!’ }, _callback=callback ) if f’origin/{ref} not in repo.refs: ref = ‘master’ msgs = [ f’nBranch {branch} does not exist at {repo_url}!’, ‘Using «master» branch for plugin, this may not work ‘ ‘with your RELEASE’ ] for msg in msgs: iocage_lib.ioc_common.logit( { ‘level’: ‘INFO’, ‘message’: msg }, _callback=callback ) # Time to make this reality repo.git.checkout(ref)

  • #1

sudo pkg upgrade
Password:
ld-elf.so.1: Shared object «libssl.so.8» not found, required by «pkg»

  • Thread Starter

  • #2

i resolve the problem:
1..pkg-static del -f pkg
2. pkg upgrade
Now it works Thanks :)

SirDice


  • #3

i resolve the problem:
1..pkg-static del -f pkg
2. pkg upgrade

This is the correct way after a major version upgrade:

Code:

pkg-static install -f pkg
pkg upgrade -f

  • Thread Starter

  • #4

This is the correct way after a major version upgrade:

Code:

pkg-static install -f pkg
pkg upgrade -f

I noticed that «pkg upgrade» after «pkg-static del -f pkg» does it automatically

SirDice


  • #5

No, it does not. It will only update packages that happen to be out of date. After a major version upgrade you must reinstall all packages, which is what pkg upgrade -f does.

  • Thread Starter

  • #6

I did it without these recommendations:
$sudo pkg-static del -f pkg
Password:
pkg-static: Warning: Major OS version upgrade detected. Running «pkg-static install -f pkg» recommended
Checking integrity… done (0 conflicting)
Deinstallation has been requested for the following 1 packages (of 0 packages in the universe):

Installed packages to be REMOVED:
pkg-1.10.5_5

Number of packages to be removed: 1

The operation will free 12 MiB.

Proceed with deinstalling packages? [y/N]: y
[1/1] Deinstalling pkg-1.10.5_5…
[1/1] Deleting files for pkg-1.10.5_5: 100%
nat:[~]$sudo pkg upgrade
The package management tool is not yet installed on your system.
Do you want to fetch and install it now? [y/N]: y
Bootstrapping pkg from pkg+http://pkg.FreeBSD.org/FreeBSD:12:amd64/quarterly, please wait…
Verifying signature with trusted certificate pkg.freebsd.org.2013102301… done
Installing pkg-1.10.5_5…
Extracting pkg-1.10.5_5: 100%
Updating FreeBSD repository catalogue…
pkg: Repository FreeBSD has a wrong packagesite, need to re-create database
Fetching meta.txz: 100% 944 B 0.9kB/s 00:01
Fetching packagesite.txz: 100% 6 MiB 2.2MB/s 00:03
Processing entries: 100%
FreeBSD repository update completed. 31468 packages processed.
All repositories are up to date.
Updating database digests format: 100%
Checking for upgrades (119 candidates): 100%
Processing candidates (119 candidates): 100%
The following 118 package(s) will be affected (of 0 checked):

Installed packages to be UPGRADED:
ca_root_nss: 3.40 -> 3.41

Installed packages to be REINSTALLED:
unixODBC-2.3.7 (ABI changed: ‘freebsd:11:x86:64’ -> ‘freebsd:12:x86:64’)
unbound-1.8.0 (ABI changed: ‘freebsd:11:x86:64’ -> ‘freebsd:12:x86:64’)
tshark-2.6.3 (ABI changed: ‘freebsd:11:
etc etc

  • #7

I just installed 12.0-STABLE on a Raspberry PI 3B and I get the same error. Running «pkg-static del -f pkg» followed by «pkg upgrade» (with and without the -f) does not resolve this issue: I still get the shared object not found error.

Does anyone have any recommendations?

  • #8

How you install 12-STABLE? Upgrade from 11.x? If yes, in which way make buildworld ..... or freebsd-upgrade ...?
And what shows error if you say that you already do pkg upgrade -f?

Give all information!

  • #9

The 12-STABLE install was directly from a .img file downloaded from freebsd.org and installed on a 16GB microSD card using «dd» on an iMac:

% sudo dd bs=1m if=FreeBSD-12.0-STABLE-arm64-aarch64-RPI3-20181213-r341991.img of=/dev/rdisk11
2560+0 records in
2560+0 records out
2684354560 bytes transferred in 193.926793 secs (13842103 bytes/sec)

Very soon after the install I attempted to install an additional port (I do not recall which) and ran into the above shared object issue. I have repeated the pkg-static del -f pkg followed by pkg upgrade actions several times, adding reboots between the steps and other variations (like running pkg upgrade with and without -f).

pkg-static del -f pkg appears to run with no errors.

The output from the pkg upgrade -f:

root@generic:~ # pkg upgrade -f
The package management tool is not yet installed on your system.
Do you want to fetch and install it now? [y/N]: y
Bootstrapping pkg from pkg+http://pkg.FreeBSD.org/FreeBSD:12:aarch64/latest, please wait…
Verifying signature with trusted certificate pkg.freebsd.org.2013102301… done
Installing pkg-1.10.5_3…
Extracting pkg-1.10.5_3: 100%
ld-elf.so.1: Shared object «libssl.so.8» not found, required by «pkg»

SirDice


  • #10

How you install 12-STABLE? Upgrade from 11.x? If yes, in which way make buildworld ….. or freebsd-upgrade …?

You can’t update/upgrade a -STABLE version with freebsd-update(8).

  • #11

root@generic:~ # pkg upgrade -f
The package management tool is not yet installed on your system.
Do you want to fetch and install it now? [y/N]: y
Bootstrapping pkg from pkg+http://pkg.FreeBSD.org/FreeBSD:12:aarch64/latest, please wait…
Verifying signature with trusted certificate pkg.freebsd.org.2013102301… done
Installing pkg-1.10.5_3…
Extracting pkg-1.10.5_3: 100%
ld-elf.so.1: Shared object «libssl.so.8» not found, required by «pkg»

I just struck this issue upgrading from 12-CURRENT to 13-CURRENT on my rpi3.

The solution was to compile the ports version of pkg and install that. It then, of course, links against the correct openssl libraries and resolves pkg’s missing libraries issue.

  • #12

That did it! Thank you.

(As soon as I read your post it did seem a bit obvious that this is the solution. Doh!)

  • #13

i resolve the problem:
1..pkg-static del -f pkg
2. pkg upgrade
Now it works Thanks :)

It works, Thank you!

  • #14

So on a raspberry pi I have to install the ports tree and compile from source? Really?
(I flashed the 12-STABLE image on RPI-B: FreeBSD-12.0-STABLE-arm-armv6-RPI-B-20190307-r344851.img)

SirDice


  • #15

So on a raspberry pi I have to install the ports tree and compile from source? Really?

You misunderstood. Read the thread again.

  • #16

The solution was to compile the ports version of pkg and install that.

What did I misunderstand?

[FONT=courier new][1/1] Deinstalling pkg-1.10.5_3…
[1/1] Deleting files for pkg-1.10.5_3: 100%
root@rpi-b:/home/freebsd # pkg upgrade
The package management tool is not yet installed on your system.
Do you want to fetch and install it now? [y/N]: y
Bootstrapping pkg from pkg+http://pkg.FreeBSD.org/FreeBSD:12:armv6/latest, please wait…
Verifying signature with trusted certificate pkg.freebsd.org.2013102301… done
Installing pkg-1.10.5_3…
Extracting pkg-1.10.5_3: 100%
ld-elf.so.1: Shared object «libssl.so.8» not found, required by «pkg»[/FONT]

  • #18

The solution was to compile the ports version of pkg and install that.

What did I misunderstand?

[FONT=courier new][1/1] Deinstalling pkg-1.10.5_3…
[1/1] Deleting files for pkg-1.10.5_3: 100%
root@rpi-b:/home/freebsd # pkg upgrade[/FONT]

What you missed was the you did not compile the ports version; you tried installing the pkg version :)

  • #19

I still don’t understand. «compile the ports version» means

[FONT=courier new]# cd /usr/ports/ports-mgmt/pkg/ && make install[/FONT]

right?

  • #20

I still don’t understand. «compile the ports version» means
[FONT=courier new]# cd /usr/ports/ports-mgmt/pkg/ && make install[/FONT]

Correct.

  • #21

And that implies:

So on a raspberry pi I have to install the ports tree and compile from source? Really?

or not? Where is my misunderstanding then?

SirDice


  • #22

Post #3:

Code:

pkg-static install -f pkg
pkg upgrade

  • #23

Post #3:

Code:

pkg-static install -f pkg
pkg upgrade

I still get the error like this.

Code:

# ldd /usr/local/sbin/pkg
/usr/local/sbin/pkg:
...
    libssl.so.8 => not found (0)
    libcrypto.so.8 => not found (0)
...
    libssl.so.8 => not found (0)
    libcrypto.so.8 => not found (0)
...

Last edited: Mar 13, 2019

Понравилась статья? Поделить с друзьями:
  • Error main file version
  • Error main file cannot be included recursively when building a preamble
  • Error main cannot start client command adb
  • Error mail command failed 550 not local sender over smtp
  • Error macro mortal kombat