def check_gpg_and_start_download(self, download_result): asc_content = download_result.pop(self.asc_url).buffer.getvalue().decode('utf-8') sig_url = list(download_result.keys())[0] res = download_result[sig_url] sig = res.buffer.getvalue().decode('utf-8').split()[0] # When we install new packages, we are executing as root and then dropping # as the user for extracting and such. However, for signature verification, # we use gpg. This one doesn't like priviledge drop (if uid = 0 and # euid = 1000) and asserts if uid != euid. # Importing the key as root as well creates new gnupg files owned as root if # new keys weren't imported first. # Consequently, run gpg as root if we needed root access or as the user # otherwise. We store the gpg public key in a temporary gnupg directory that # will be removed under the same user rights (this directory needs to be owned # by the same user id to not be rejected by gpg).Z if self.need_root_access: with as_root(): with tempfile.TemporaryDirectory() as tmpdirname: self._check_gpg_signature(tmpdirname, asc_content, sig) else: with tempfile.TemporaryDirectory() as tmpdirname: self._check_gpg_signature(tmpdirname, asc_content, sig) # you get and store self.download_url url = re.sub('.sig', '', sig_url) if url is None: logger.error("Download page changed its syntax or is not parsable (missing url)") UI.return_main_screen(status_code=1) logger.debug("Found download link for {}".format(url)) self.download_requests.append(DownloadItem(url, None)) self.start_download_and_install()
def get_metadata(self, result): """Download files to download + and download license license and check it""" logger.debug("Parse download metadata") error_msg = result[self.download_page].error if error_msg: logger.error("An error occurred while downloading {}: {}".format(self.download_page, error_msg)) UI.return_main_screen() url = None for line in result[self.download_page].buffer: line = line.decode() p = re.search(r'<a.*href="(.*)">.*for Linux.*', line) with suppress(AttributeError): url = p.group(1) logger.debug("Found download link for {}".format(url)) if url is None: logger.error("Download page changed its syntax or is not parsable") UI.return_main_screen() self.download_requests.append(DownloadItem(url, Checksum(self.checksum_type, None), headers=self.headers)) logger.debug("Downloading License page") DownloadCenter([DownloadItem(self.license_url, headers=self.headers)], self.check_external_license, download=False)
def get_metadata_and_check_license(self, result): """Get latest version and append files to download""" logger.debug("Set download metadata") error_msg = result[self.download_page].error if error_msg: logger.error("An error occurred while downloading {}: {}".format(self.download_page, error_msg)) UI.return_main_screen(status_code=1) version = '' version_re = r'Dart SDK (.*) api docs' for line in result[self.download_page].buffer: p = re.search(version_re, line.decode()) with suppress(AttributeError): version = p.group(1) break else: logger.error("Download page changed its syntax or is not parsable") UI.return_main_screen(status_code=1) tag_machine = 'x64' if platform.machine() == 'i686': tag_machine = 'ia32' url = "https://storage.googleapis.com/dart-archive/channels/stable/release/{}/sdk/dartsdk-linux-{}-release.zip"\ .format(version, tag_machine) logger.debug("Found download link for {}".format(url)) self.download_requests.append(DownloadItem(url, None)) self.start_download_and_install()
def confirm_path(self, path_dir=""): """Confirm path dir""" if not path_dir: logger.debug("No installation path provided. Requesting one.") UI.display(InputText("Choose installation path:", self.confirm_path, self.install_path)) return logger.debug("Installation path provided. Checking if exists.") with suppress(FileNotFoundError): if os.listdir(path_dir): # we already told we were ok to overwrite as it was the previous install path if path_dir not in self._paths_to_clean: if path_dir == "/": logger.error("This doesn't seem wise. We won't let you shoot in your feet.") self.confirm_path() return self.install_path = path_dir # we don't set it before to not repropose / as installation path UI.display(YesNo("{} isn't an empty directory, do you want to remove its content and install " "there?".format(path_dir), self.set_installdir_to_clean, UI.return_main_screen)) return self.install_path = path_dir if self.desktop_filename: self.exec_path = os.path.join(self.install_path, self.required_files_path[0]) # if self.exec_rel_path: # self.exec_path = os.path.join(self.install_path, self.exec_rel_path) self.download_provider_page()
def get_metadata_and_check_license(self, result): """Download files to download + license and check it""" logger.debug("Parse download metadata") error_msg = result[self.download_page].error if error_msg: logger.error("An error occurred while downloading {}: {}".format(self.download_page, error_msg)) UI.return_main_screen(status_code=1) in_download = False sig_url = None for line in result[self.download_page].buffer: line_content = line.decode() (new_sig_url, in_download) = self.parse_download_link(line_content, in_download) if str(new_sig_url) > str(sig_url): # Avoid fetching development snapshots if 'DEVELOPMENT-SNAPSHOT' not in new_sig_url: tmp_release = re.search("ubuntu(.....).tar", new_sig_url).group(1) if tmp_release <= get_current_ubuntu_version(): sig_url = new_sig_url if not sig_url: logger.error("Download page changed its syntax or is not parsable") UI.return_main_screen(status_code=1) DownloadCenter(urls=[DownloadItem(sig_url, None), DownloadItem(self.asc_url, None)], on_done=self.check_gpg_and_start_download, download=False)
def get_metadata_and_check_license(self, result): logger.debug("Fetched download page, parsing.") page = result[self.download_page] error_msg = page.error if error_msg: logger.error("An error occurred while downloading {}: {}".format(self.download_page, error_msg)) UI.return_main_screen(status_code=1) try: key, content = json.loads(page.buffer.read().decode()).popitem() download_url = content[0]['downloads']['linux']['link'] checksum_url = content[0]['downloads']['linux']['checksumLink'] except (json.JSONDecodeError, IndexError): logger.error("Can't parse the download URL from the download page.") UI.return_main_screen(status_code=1) logger.debug("Found download URL: " + download_url) logger.debug("Downloading checksum first, from " + checksum_url) def checksum_downloaded(results): checksum_result = next(iter(results.values())) # Just get the first. if checksum_result.error: logger.error(checksum_result.error) UI.return_main_screen(status_code=1) checksum = checksum_result.buffer.getvalue().decode('utf-8').split()[0] logger.info('Obtained SHA256 checksum: ' + checksum) self.download_requests.append(DownloadItem(download_url, checksum=Checksum(ChecksumType.sha256, checksum), ignore_encoding=True)) self.start_download_and_install() DownloadCenter([DownloadItem(checksum_url)], on_done=checksum_downloaded, download=False)
def download_provider_page(self): # grab initial download link from homepage response = urllib.request.urlopen('https://processing.org/download/?processing') htmlDocument = response.read() soupDocument = BeautifulSoup(htmlDocument, 'html.parser') arch = platform.machine() plat = '' if arch == 'i686': plat = 'linux32' elif arch == 'x86_64': plat = 'linux64' else: logger.error("Unsupported architecture: {}".format(arch)) UI.return_main_screen() downloads = soupDocument.body.find('div', attrs={'class': 'downloads'}) self.version = downloads.find('span', attrs={'class': 'version'}).text dl = downloads.find('ul', attrs={'class': 'current-downloads'}) fileURL = '' for link in dl.find_all('a'): url = link.get('href') if plat in url: fileURL = url break self.download_requests.append(DownloadItem(fileURL)) self.start_download_and_install()
def download_and_requirements_done(self): # wait for both side to be done if self._download_done_callback_called or (not self.result_download or not self.result_requirement): return self._download_done_callback_called = True self.pbar.finish() # display eventual errors error_detected = False if self.result_requirement.error: logger.error("Package requirements can't be met: {}".format(self.result_requirement.error)) error_detected = True # check for any errors and collect fds fds = [] for url in self.result_download: if self.result_download[url].error: logger.error(self.result_download[url].error) error_detected = True fds.append(self.result_download[url].fd) if error_detected: UI.return_main_screen(status_code=1) # now decompress self.decompress_and_install(fds)
def post_install(self): """Add go necessary env variables""" add_env_to_user( self.name, {"PATH": {"value": os.path.join(self.install_path, "bin")}, "GOROOT": {"value": self.install_path}}, ) UI.delayed_display(DisplayMessage(_("You need to restart a shell session for your installation to work")))
def get_metadata(self, result): """Download files to download + and download license license and check it""" logger.debug("Parse download metadata") error_msg = result[self.download_page].error if error_msg: logger.error("An error occurred while downloading {}: {}".format(self.download_page, error_msg)) UI.return_main_screen(status_code=1) arch = platform.machine() download_re = r'\'linux64\': \'([^\']+)\'' if arch == 'i686': download_re = r'\'linux32\': \'([^\']+)\'' url = None for line in result[self.download_page].buffer: line = line.decode() p = re.search(download_re, line) with suppress(AttributeError): url = p.group(1) logger.debug("Found download link for {}".format(url)) if url is None: logger.error("Download page changed its syntax or is not parsable") UI.return_main_screen(status_code=1) self.download_requests.append(DownloadItem(url, Checksum(self.checksum_type, None), headers=self.headers)) if not self.auto_accept_license: logger.debug("Downloading License page") DownloadCenter([DownloadItem(self.license_url, headers=self.headers)], self.check_external_license, download=False) else: self.start_download_and_install()
def post_install(self): """Add rust necessary env variables""" add_env_to_user(self.name, {"PATH": {"value": "{}:{}".format(os.path.join(self.install_path, "rustc", "bin"), os.path.join(self.install_path, "cargo", "bin"))}, "LD_LIBRARY_PATH": {"value": os.path.join(self.install_path, "rustc", "lib")}}) UI.delayed_display(DisplayMessage(_("You need to restart your current shell session for your {} installation " "to work properly").format(self.name)))
def get_metadata_and_check_license(self, result): """Get the latest version and trigger the download of the download_page file. :param result: the file downloaded by DownloadCenter, contains a web page """ # Processing the string to obtain metadata (version) try: url_version_str = result[self.download_page].buffer.read().decode('utf-8') except AttributeError: # The file could not be parsed or there is no network connection logger.error("The download page changed its syntax or is not parsable") UI.return_main_screen(status_code=1) preg = re.compile(".*/images_www/v6/download/.*") for line in url_version_str.split("\n"): if preg.match(line): line = line.replace("var PAGE_ARTIFACTS_LOCATION = \"/images" "_www/v6/download/", "").replace("/\";", "").replace('/final', '') self.version = line.strip() if not self.version: # Fallback logger.error("Could not determine latest version") UI.return_main_screen(status_code=1) self.version_download_page = "https://netbeans.org/images_www/v6/download/" \ "{}/final/js/files.js".format(self.version) DownloadCenter([DownloadItem(self.version_download_page)], self.parse_download_page_callback, download=False)
def get_metadata_and_check_license(self, result): logger.debug("Fetched download page, parsing.") page = result[self.download_page] error_msg = page.error if error_msg: logger.error("An error occurred while downloading {}: {}".format(self.download_page_url, error_msg)) UI.return_main_screen(status_code=1) soup = BeautifulSoup(page.buffer) link = soup.find('a', text="HTTPS") if link is None: logger.error("Can't parse the download URL from the download page.") UI.return_main_screen(status_code=1) download_url = link.attrs['href'] checksum_url = download_url + '.sha256' logger.debug("Found download URL: " + download_url) logger.debug("Downloading checksum first, from " + checksum_url) def checksum_downloaded(results): checksum_result = next(iter(results.values())) # Just get the first. if checksum_result.error: logger.error(checksum_result.error) UI.return_main_screen(status_code=1) checksum = checksum_result.buffer.getvalue().decode('utf-8').split()[0] logger.info('Obtained SHA256 checksum: ' + checksum) self.download_requests.append(DownloadItem(download_url, checksum=Checksum(ChecksumType.sha256, checksum), ignore_encoding=True)) self.start_download_and_install() DownloadCenter([DownloadItem(checksum_url)], on_done=checksum_downloaded, download=False)
def _display(self, contentType): # print depending on the content type while True: try: if isinstance(contentType, InputText): contentType.run_callback(result=rlinput(contentType.content, contentType.default_input)) elif isinstance(contentType, LicenseAgreement): print(contentType.content) contentType.choose(answer=input(contentType.input)) elif isinstance(contentType, TextWithChoices): contentType.choose(answer=input(contentType.prompt)) elif isinstance(contentType, DisplayMessage): print(contentType.text) elif isinstance(contentType, UnknownProgress): if not contentType.bar: contentType.bar = ProgressBar(widgets=[BouncingBar()]) with suppress(StopIteration): # pulse and add a timeout callback contentType.bar(contentType._iterator()).next() UI.delayed_display(contentType) # don't recall the callback return False else: logger.error("Unexcepted content type to display to CLI UI: {}".format(contentType)) MainLoop().quit(status_code=1) break except InputError as e: logger.error(str(e)) continue
def post_install(self): """Add necessary environment variables""" add_env_to_user(self.name, {"ANDROID_HOME": {"value": self.install_path, "keep": False}}) # add "platform-tools" to PATH to ensure "adb" can be run once the platform tools are installed via # the SDK manager add_env_to_user( self.name, { "PATH": { "value": [os.path.join("$ANDROID_HOME", "tools"), os.path.join("$ANDROID_HOME", "platform-tools")] } }, ) UI.delayed_display( DisplayMessage( _("You need to restart your current shell session for your {} installation " "to work properly").format( self.name ) ) ) # print wiki page message UI.delayed_display( DisplayMessage( "SDK installed in {}. More information on how to use it on {}".format( self.install_path, "https://developer.android.com/sdk/installing/adding-packages.html" ) ) )
def post_install(self): """Add necessary environment variables""" add_env_to_user(self.name, {"NDK_ROOT": {"value": self.install_path, "keep": False}}) # print wiki page message UI.display(DisplayMessage("NDK installed in {}. More information on how to use it on {}".format( self.install_path, "https://developer.android.com/tools/sdk/ndk/index.html#GetStarted")))
def post_install(self): """Add nodejs necessary env variables and move module folder""" subprocess.call([os.path.join(self.install_path, "bin", "npm"), "config", "set", "prefix", "~/.node_modules"]) add_env_to_user(self.name, {"PATH": {"value": "{}:{}".format(os.path.join(self.install_path, "bin"), os.path.join(os.path.expanduser('~'), ".node_modules", "bin"))}}) UI.delayed_display(DisplayMessage(_("You need to restart your current shell session for your {} installation " "to work properly").format(self.name)))
def decompress_and_install(self, fd): UI.display(DisplayMessage("Installing {}".format(self.name))) # empty destination directory if reinstall for dir_to_remove in self._paths_to_clean: with suppress(FileNotFoundError): shutil.rmtree(dir_to_remove) Decompressor({fd: Decompressor.DecompressOrder(dir=self.dir_to_decompress_in_tarball, dest=self.install_path)}, self.decompress_and_install_done) UI.display(UnknownProgress(self.iterate_until_install_done))
def setup(self, arg_install_path=None): self.arg_install_path = arg_install_path super().setup() # first step, check if installed if self.is_installed: UI.display(YesNo("{} is already installed on your system, do you want to reinstall " "it anyway?".format(self.name), self.reinstall, UI.return_main_screen)) else: self.confirm_path(arg_install_path)
def test_call_display(self, mocksys): """We call the display method from the UIPlug""" UI.display(self.contentType) self.start_glib_mainloop() self.wait_for_mainloop_shutdown() self.assertTrue(self.mockUIPlug._display.called) self.assertIsNotNone(self.mainloop_thread) self.assertIsNotNone(self.display_thread) self.assertEqual(self.mainloop_thread, self.display_thread)
def post_install(self): """Add nodejs necessary env variables and move module folder""" if not self.prefix_set(): with open(os.path.join(os.environ['HOME'], '.npmrc'), 'a+') as file: file.write("prefix = ${HOME}/.npm_modules\n") add_env_to_user(self.name, {"PATH": {"value": "{}:{}".format(os.path.join(self.install_path, "bin"), os.path.join(os.path.expanduser('~'), ".npm_modules", "bin"))}}) UI.delayed_display(DisplayMessage(self.RELOGIN_REQUIRE_MSG.format(self.name)))
def _check_gpg_signature(self, gnupgdir, asc_content, sig): """check gpg signature (temporary stock in dir)""" gpg = gnupg.GPG(gnupghome=gnupgdir) imported_keys = gpg.import_keys(asc_content) if imported_keys.count == 0: logger.error("Keys not valid") UI.return_main_screen(status_code=1) verify = gpg.verify(sig) if verify is False: logger.error("Signature not valid") UI.return_main_screen(status_code=1)
def run_for(self, args): """Running commands from args namespace""" # try to call default framework if any if not args.framework: if not self.default_framework: message = "A default framework for category {} was requested where there is none".format(self.name) logger.error(message) UI.return_main_screen(status_code=1) self.default_framework.run_for(args) return self.frameworks[args.framework].run_for(args)
def post_install(self): """Create the Unity 3D launcher and setuid chrome sandbox""" with futures.ProcessPoolExecutor(max_workers=1) as executor: # chrome sandbox requires this: https//code.google.com/p/chromium/wiki/LinuxSUIDSandbox f = executor.submit(_chrome_sandbox_setuid, os.path.join(self.install_path, "Editor", "chrome-sandbox")) if not f.result(): UI.return_main_screen(exit_status=1) create_launcher(self.desktop_filename, get_application_desktop_file(name=_("Unity3D Editor"), icon_path=os.path.join(self.install_path, "unity-editor-icon.png"), exec=os.path.join(self.install_path, "Editor", "Unity"), comment=self.description, categories="Development;IDE;"))
def test_call_delayed_display(self, mocksys): """We call the display method from the UIPlug in delayed_display with 50ms waiting""" UI.delayed_display(self.contentType) now = time() self.start_glib_mainloop() self.wait_for_mainloop_shutdown() self.assertTrue(self.mockUIPlug._display.called) self.assertIsNotNone(self.mainloop_thread) self.assertIsNotNone(self.display_thread) self.assertEqual(self.mainloop_thread, self.display_thread) self.assertTrue(self.time_display_call - now > 0.05)
def get_metadata_and_check_license(self, result): """Download files to download + license and check it""" logger.debug("Parse download metadata") error_msg = result[self.download_page].error if error_msg: logger.error("An error occurred while downloading {}: {}".format(self.download_page, error_msg)) UI.return_main_screen(status_code=1) url, checksum = (None, None) with StringIO() as license_txt: in_license = False in_download = False for line in result[self.download_page].buffer: line_content = line.decode() if self.expect_license and not self.auto_accept_license: in_license = self.parse_license(line_content, license_txt, in_license) # always take the first valid (url, checksum) if not match_last_link is set to True: download = None if url is None or (self.checksum_type and not checksum) or self.match_last_link: (download, in_download) = self.parse_download_link(line_content, in_download) if download is not None: (newurl, new_checksum) = download url = newurl if newurl is not None else url checksum = new_checksum if new_checksum is not None else checksum if url is not None: if self.checksum_type and checksum: logger.debug("Found download link for {}, checksum: {}".format(url, checksum)) elif not self.checksum_type: logger.debug("Found download link for {}".format(url)) if url is None: logger.error("Download page changed its syntax or is not parsable (url missing)") UI.return_main_screen(status_code=1) if (self.checksum_type and checksum is None): logger.error("Download page changed its syntax or is not parsable (checksum missing)") logger.error("URL is: {}".format(url)) UI.return_main_screen(status_code=1) self.download_requests.append(DownloadItem(url, Checksum(self.checksum_type, checksum))) if license_txt.getvalue() != "": logger.debug("Check license agreement.") UI.display(LicenseAgreement(strip_tags(license_txt.getvalue()).strip(), self.start_download_and_install, UI.return_main_screen)) elif self.expect_license and not self.auto_accept_license: logger.error("We were expecting to find a license on the download page, we didn't.") UI.return_main_screen(status_code=1) else: self.start_download_and_install()
def decompress_and_install(self, fds): # if icon, we grab the icon name to reference it later on for fd in fds: if fd.name.endswith(".svg"): orig_icon_name = os.path.basename(fd.name) break else: logger.error("We couldn't download the Twine icon") UI.return_main_screen(exit_status=1) super().decompress_and_install(fds) # rename the asset logo self.icon_name = "logo.svg" os.rename(os.path.join(self.install_path, orig_icon_name), os.path.join(self.install_path, self.icon_name))
def checksum_downloaded(results): checksum_result = next(iter(results.values())) # Just get the first. if checksum_result.error: logger.error(checksum_result.error) UI.return_main_screen(status_code=1) checksum = checksum_result.buffer.getvalue().decode('utf-8').split()[0] logger.info('Obtained SHA256 checksum: ' + checksum) self.download_requests.append(DownloadItem(download_url, checksum=Checksum(ChecksumType.sha256, checksum), ignore_encoding=True)) self.start_download_and_install()
def get_sha_and_start_download(self, download_result): res = download_result[self.sha1_url] sha1 = res.buffer.getvalue().decode('utf-8').split()[0] url = re.sub('.sha1', '', self.sha1_url) if url is None: logger.error("Download page changed its syntax or is not parsable (missing url)") UI.return_main_screen(status_code=1) if sha1 is None: logger.error("Download page changed its syntax or is not parsable (missing checksum)") UI.return_main_screen(status_code=1) logger.debug("Found download link for {}, checksum: {}".format(url, sha1)) self.download_requests.append(DownloadItem(url, Checksum(ChecksumType.sha1, sha1))) self.start_download_and_install()
def post_install(self): """Create the Arduino launcher""" icon_path = join(self.install_path, 'lib', 'arduino_icon.ico') comment = _("The Arduino Software IDE") categories = "Development;IDE;" create_launcher(self.desktop_filename, get_application_desktop_file(name=_("Arduino"), icon_path=icon_path, exec='"{}" %f'.format(self.exec_path), comment=comment, categories=categories)) if not self.was_in_arduino_group: UI.delayed_display(DisplayMessage(_("You need to logout and login again for your installation to work")))
def post_install(self): """Print wiki page message""" UI.display(DisplayMessage("NDK installed in {}. More information on how to use it on {}".format( self.install_path, "https://developer.android.com/tools/sdk/ndk/index.html#GetStarted")))
def post_install(self): """Add the Kotlin binary dir to PATH""" add_env_to_user(self.name, {"PATH": {"value": os.path.join(self.install_path, "bin")}}) UI.delayed_display(DisplayMessage(self.RELOGIN_REQUIRE_MSG.format(self.name)))
def post_install(self): """Add phantomjs necessary env variables""" add_env_to_user(self.name, {"PATH": {"value": os.path.join(self.install_path, "bin")}}) UI.delayed_display(DisplayMessage(self.RELOGIN_REQUIRE_MSG.format(self.name)))
def remove(self): """Method call to remove the current framework""" if not self.is_installed: logger.error(_("You can't remove {} as it isn't installed".format(self.name))) UI.return_main_screen(status_code=1) return
def get_metadata_and_check_license(self, result): """Download files to download + license and check it""" logger.debug("Parse download metadata") error_msg = result[self.download_page].error if error_msg: logger.error("An error occurred while downloading {}: {}".format( self.download_page, error_msg)) UI.return_main_screen(status_code=1) self.new_download_url = None self.shasum_read_method = hasattr(self, 'get_sha_and_start_download') with StringIO() as license_txt: url, checksum = (None, None) page = result[self.download_page] if self.json is True: logger.debug("Using json parser") try: latest = json.loads(page.buffer.read().decode()) # On a download from github, if the page is not .../releases/latest # we want to download the latest version (beta/development) # So we get the first element in the json tree. # In the framework we only change the url and this condition is satisfied. if self.download_page.startswith("https://api.github.com") and\ not self.download_page.endswith("/latest"): latest = latest[0] url = None in_download = False (url, in_download) = self.parse_download_link( latest, in_download) if not url: if not self.url: raise IndexError else: logger.debug( "We set a temporary url while fetching the checksum" ) url = self.url except (json.JSONDecodeError, IndexError): logger.error( "Can't parse the download URL from the download page.") UI.return_main_screen(status_code=1) logger.debug("Found download URL: " + url) else: in_license = False in_download = False for line in page.buffer: line_content = line.decode() if self.expect_license and not self.auto_accept_license: in_license = self.parse_license( line_content, license_txt, in_license) # always take the first valid (url, checksum) if not match_last_link is set to True: download = None # if not in_download: if (url is None or (self.checksum_type and not checksum) or self.match_last_link) and\ not(self.shasum_read_method and self.new_download_url): (download, in_download) = self.parse_download_link( line_content, in_download) if download is not None: (newurl, new_checksum) = download url = newurl if newurl is not None else url checksum = new_checksum if new_checksum is not None else checksum if url is not None: if self.checksum_type and checksum: logger.debug( "Found download link for {}, checksum: {}". format(url, checksum)) elif not self.checksum_type: logger.debug( "Found download link for {}".format(url)) if hasattr(self, 'get_sha_and_start_download'): logger.debug('Run get_sha_and_start_download') DownloadCenter( urls=[DownloadItem(self.new_download_url, None)], on_done=self.get_sha_and_start_download, download=False) else: self.check_data_and_start_download(url, checksum, license_txt)
def post_install(self): """Add go necessary env variables""" add_env_to_user(self.name, {"PATH": {"value": os.path.join(self.install_path, "bin")}, "GOROOT": {"value": self.install_path, "keep": False}}) UI.delayed_display(DisplayMessage(_("You need to restart your current shell session for your {} installation " "to work properly").format(self.name)))