Example #1
0
        /// <summary>
        /// Handler for the MergeWorker.OnRealMerge event.
        /// </summary>
        /// <param name="sender">the merge worker</param>
        /// <param name="e">merge event args</param>
        public void MergeWorker_OnRealMerge(object sender, MergeEventArgs e)
        {
            if (e.FetchOnly)
                Console.Write("\n>>> Fetching (");
            else
                Console.Write("\n>>> Merging (");

            Console.ForegroundColor = ConsoleColor.Yellow;
            Console.Write(e.CurrentIter);

            Console.ResetColor();
            Console.Write(" of ");

            Console.ForegroundColor = ConsoleColor.Yellow;
            Console.Write(e.TotalMerges);

            Console.ResetColor();
            Console.Write(") ");

            Console.ForegroundColor = ConsoleColor.Green;
            Console.Write(e.Distribution.ToString());

            Console.ResetColor();
            Console.Write("\n");
        }
Example #2
0
        /// <summary>
        /// Handler for the MergeWorker.OnPretendMerge event.
        /// </summary>
        /// <param name="sender">the merge worker</param>
        /// <param name="e">merge event args</param>
        public void MergeWorker_OnPretendMerge(object sender, MergeEventArgs e)
        {
            _numpkgs++;
            _dloadsz += e.Distribution.TotalSize;

            string distrepo = e.Distribution.PortsTree.Repository;
            if (!_repolst.Contains(distrepo))
                _repolst.Add(distrepo);

            if (e.HardMask)
                _hardmask.Add(e.Distribution.Atom);

            if (e.KeywordMask)
                _kwmask.Add(new Tuple<Atom, string[]>(e.Distribution.Atom, e.KeywordsNeeded));

            Console.Write("[");
            if (e.Selected)
                Console.ForegroundColor = ConsoleColor.Green;
            else
                Console.ForegroundColor = ConsoleColor.DarkGreen;
            Console.Write("port  ");
            Console.ResetColor();

            if (e.Flags.HasFlag(MergeFlags.BlockUnresolved) || e.Flags.HasFlag(MergeFlags.BlockResolved)) {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.Write("{0}", e.Flags.HasFlag(MergeFlags.BlockUnresolved) ? "B" : "b");
                Console.ResetColor();
            } else if (e.Flags.HasFlag(MergeFlags.Interactive)) {
                Console.ForegroundColor = ConsoleColor.Yellow;
                Console.Write("I");
                Console.ResetColor();
            } else
                Console.Write(" ");

            Console.ForegroundColor = ConsoleColor.Green;
            Console.Write("{0}", e.Flags.HasFlag(MergeFlags.New) ? "N" : " ");
            Console.ResetColor();

            if (e.Flags.HasFlag(MergeFlags.Replacing)) {
                Console.ForegroundColor = ConsoleColor.Yellow;
                Console.Write("R");
                Console.ResetColor();
            } else if (e.Flags.HasFlag(MergeFlags.Slot)) {
                Console.ForegroundColor = ConsoleColor.Green;
                Console.Write("S");
                Console.ResetColor();
            } else
                Console.Write(" ");

            if (e.Flags.HasFlag(MergeFlags.FetchNeeded) || e.Flags.HasFlag(MergeFlags.FetchExists)) {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.Write("{0}", e.Flags.HasFlag(MergeFlags.FetchNeeded) ? "F" : "f");
                Console.ResetColor();
            } else
                Console.Write(" ");

            Console.ForegroundColor = ConsoleColor.Cyan;
            Console.Write("{0}", e.Flags.HasFlag(MergeFlags.Updating) ? "U" : " ");
            Console.ResetColor();

            Console.ForegroundColor = ConsoleColor.Blue;
            Console.Write("{0}", e.Flags.HasFlag(MergeFlags.Downgrading) ? "D" : " ");
            Console.ResetColor();

            if (e.HardMask) {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.Write("M");
                Console.ResetColor();
            } else if (e.KeywordMask) {
                Console.ForegroundColor = ConsoleColor.Yellow;
                Console.Write("~");
                Console.ResetColor();
            } else
                Console.Write(" ");

            Console.Write("]");
            if (e.Selected)
                Console.ForegroundColor = ConsoleColor.Green;
            else
                Console.ForegroundColor = ConsoleColor.DarkGreen;
            Console.Write(" {0}", e.Distribution.ToString());
            Console.ResetColor();

            if (!e.Flags.HasFlag(MergeFlags.New) && !e.Flags.HasFlag(MergeFlags.Replacing)) {
                Console.ForegroundColor = ConsoleColor.Blue;
                Console.Write(" [{0}]", e.Previous.Version.ToString());
                Console.ResetColor();
            }

            StringBuilder sb = new StringBuilder(11);
            Win32.StrFormatByteSize(e.Distribution.TotalSize, sb, sb.Capacity);
            Console.Write(" {0}", sb.ToString());

            Console.ForegroundColor = ConsoleColor.Cyan;
            Console.Write(" [{0}]", _repolst.IndexOf(distrepo));
            Console.ResetColor();

            Console.Write("\n");
        }
Example #3
0
        /// <summary>
        /// Determines the packages needed for merging, including dependencies if necessary.
        /// </summary>
        /// <param name="distarr">packages selected for merging</param>
        /// <param name="mopts">merge options</param>
        /// <param name="downloader">the downloader</param>
        /// <param name="scheduled">output list of packages scheduled for merge</param>
        private void ScheduleMerges(IDistribution[] distarr, MergeOptions mopts, Downloader downloader, 
            out List<MergeEventArgs> scheduled)
        {
            scheduled = new List<MergeEventArgs>();

            DependencyGraph dg = DependencyGraph.Compute(distarr);
            IDistribution[] distdeparr = dg.SortedNodes.ToArray();

            DependencyGraph.Conflict[] conflicts = dg.FindSlotConflicts();
            if (conflicts.Length > 0)
                throw new SlotConflictException(conflicts);

            for (int i = 0; i < distdeparr.Length; i++) {
                IDistribution dist = distdeparr[i];
                Atom current = _pkgmgr
                    .FindPackages(Atom.Parse(dist.Package.FullName, AtomParseOptions.WithoutVersion))
                    .Where(n => n.Slot == dist.Slot)
                    .SingleOrDefault();
                bool realselect = distarr.Contains(dist);

                if (!realselect && current != null && !mopts.HasFlag(MergeOptions.Deep) && dg.CheckSatisfies(current))
                    dist = dist.PortsTree.Lookup(current);

                MergeEventArgs mea = new MergeEventArgs();
                mea.Previous = current;
                mea.Selected = realselect && !mopts.HasFlag(MergeOptions.OneShot);
                mea.Distribution = dist;
                mea.FetchOnly = mopts.HasFlag(MergeOptions.FetchOnly);

                mea.HardMask = dist.PortsTree.IsHardMasked(dist);
                mea.KeywordMask = dist.PortsTree.IsKeywordMasked(dist);

                mea.KeywordsNeeded = dist.Keywords
                    .Where(kw => _cfg.AcceptKeywords.Contains(kw) ||
                                 _cfg.AcceptKeywords.Contains(Distribution.GetKeywordName(kw)))
                    .ToArray();

                if (!mopts.HasFlag(MergeOptions.Pretend) && (mea.HardMask || mea.KeywordMask))
                    throw new MaskedPackageException(dist.Package.FullName);

                if (current == null)
                    mea.Flags |= MergeFlags.New;
                if (!mea.Flags.HasFlag(MergeFlags.New) && current.Version == dist.Version)
                    mea.Flags |= MergeFlags.Replacing;
                if (!mea.Flags.HasFlag(MergeFlags.New) && !mea.Flags.HasFlag(MergeFlags.Replacing))
                    mea.Flags |= MergeFlags.Updating;
                if (!mea.Flags.HasFlag(MergeFlags.New) && current.Version > dist.Version)
                    mea.Flags |= MergeFlags.Downgrading;
                if (dist.Slot > 0)
                    mea.Flags |= MergeFlags.Slot;
                if (dist.Interactive)
                    mea.Flags |= MergeFlags.Interactive;
                /* TODO block */

                if (mea.Flags.HasFlag(MergeFlags.Updating))
                    mea.Selected = _pkgmgr.IsSelected(dist.Atom);

                if (dist.FetchRestriction && Distribution.CheckSourcesExist(dist, _cfg.DistFilesDir))
                    mea.Flags |= MergeFlags.FetchExists;
                else if (dist.FetchRestriction)
                    mea.Flags |= MergeFlags.FetchNeeded;

                if (mea.Flags.HasFlag(MergeFlags.Replacing) &&
                        (!realselect || mopts.HasFlag(MergeOptions.NoReplace)) && !mopts.HasFlag(MergeOptions.EmptyTree))
                    continue;

                if (mea.Flags.HasFlag(MergeFlags.FetchNeeded) && !mopts.HasFlag(MergeOptions.Pretend)) {
                    throw new InstallException("Fetch restriction is enabled for " + dist.ToString()
                        + "\nCopy the package archive into " + _cfg.DistFilesDir);
                }

                if (!(mea.Flags.HasFlag(MergeFlags.FetchExists) || mea.Flags.HasFlag(MergeFlags.FetchNeeded)))
                    mea.FetchHandle = downloader.Enqueue(dist);

                scheduled.Add(mea);
            }
        }
Example #4
0
        /// <summary>
        /// Handler for the MergeWorker.OnInstall event.
        /// </summary>
        /// <param name="sender">the merge worker</param>
        /// <param name="e">merge event args</param>
        public void MergeWorker_OnInstall(object sender, MergeEventArgs e)
        {
            Console.Write("\n>>> Installing ");
            Console.ForegroundColor = ConsoleColor.Green;
            Console.Write(e.Distribution.ToString());

            Console.ResetColor();
            Console.Write(" into live file system\n");
        }
Example #5
0
        /// <summary>
        /// Merge a single package into the system.
        /// </summary>
        /// <param name="mea">merge event arguments</param>
        /// <param name="mopts">merge options</param>
        /// <param name="downloader">the downloader</param>
        /// <param name="rootdir">root directory</param>
        private void MergeOne(MergeEventArgs mea, MergeOptions mopts, Downloader downloader, DirectoryInfo rootdir)
        {
            IDistribution dist = mea.Distribution;
            uint rc = 0;

            if (mopts.HasFlag(MergeOptions.Pretend)) {
                if (this.OnPretendMerge != null)
                    this.OnPretendMerge.Invoke(this, mea);

                return;
            }

            if (this.OnRealMerge != null)
                this.OnRealMerge.Invoke(this, mea);

            if (mea.HardMask || mea.KeywordMask)
                throw new MaskedPackageException(mea.Distribution.Package.FullName);

            if (dist.PlatformSources.Length > 0) {
                if (mea.FetchHandle != Guid.Empty && !downloader.Peek(mea.FetchHandle)) {
                    _log.Info("Fetching files in the background... please wait");
                    _log.InfoFormat("See {0} for fetch progress", downloader.LogFile);
                    downloader.WaitFor(mea.FetchHandle);
                }

                _log.InfoFormat("Checking package digests");

                foreach (SourceFile src in dist.PlatformSources) {
                    FileInfo distfile = new FileInfo(_cfg.DistFilesDir + @"\" + src.LocalName);

                    if (!Md5Sum.Check(distfile.FullName, src.Digest, Md5Sum.MD5SUMMODE.BINARY)) {
                        _log.ErrorFormat("Digest check failed for {0}", distfile.FullName);
                        throw new InstallException("Computed digest doesn't match expected value.");
                    }
                }
            }

            if (mopts.HasFlag(MergeOptions.FetchOnly))
                return;

            SandboxDirectory sbox = SandboxDirectory.Create();
            _log.DebugFormat("Created sandbox directory: {0}", sbox.Root.FullName);

            IInstallProject installer = dist.GetInstallProject(sbox);
            if (installer == null)
                throw new InstallException("Encountered missing or invalid installer project.");

            bool runmake = installer.HasSrcUnpackTarget ||
                           installer.HasSrcCompileTarget ||
                           installer.HasSrcInstallTarget ||
                           installer.HasSrcTestTarget;
            if (runmake && (rc = this.SpawnSandboxHost(sbox, installer)) != 0) {
                _log.DebugFormat("sandbox host return code: {0}", rc);
                throw new InstallException("Installation failed. See previous errors.");
            }

            if (this.OnInstall != null)
                this.OnInstall.Invoke(this, mea);

            if (_cfg.CollisionDetect && this.DetectCollisions(sbox.ImageDir, dist.Atom))
                throw new InstallException("File collision(s) were detected.");

            if (mea.Previous != null) {
                _log.Debug("Trashing files from previous installation");
                FileTuple[] oldfiles = _pkgmgr.QueryPackageFiles(mea.Previous);

                foreach (FileTuple ft in oldfiles) {
                    if (ft.Item2 != FileType.Directory || !this.IsProtected(ft.Item1))
                        TrashWorker.AddFile(ft.Item1, _pkgmgr);
                }
            }

            FileTuple[] files = null;
            FileTuple[] shortcuts = null;

            if (installer.HasPkgPreInstTarget) {
                _log.Info("Executing pre-install tasks...");
                installer.PkgPreInst();
            }

            IntPtr wow64oldval = IntPtr.Zero;
            if (Environment.Is64BitOperatingSystem && !Environment.Is64BitProcess) {
                if (!Wow64DisableWow64FsRedirection(out wow64oldval))
                    throw new InstallException("Failed to disable Wow64 file system redirection.");
            }

            try {
                this.InstallImage(sbox.ImageDir, rootdir, out files);
            } finally {
                if (Environment.Is64BitOperatingSystem && !Environment.Is64BitProcess)
                    Wow64RevertWow64FsRedirection(wow64oldval);
            }

            this.InstallImage(
                sbox.LinkDir,
                new DirectoryInfo(Environment.GetFolderPath(Environment.SpecialFolder.CommonStartMenu)),
                out shortcuts);

            FileTuple[] allfiles = files.Union(shortcuts).ToArray();
            Dictionary<string, string> metadata = new Dictionary<string, string>();
            metadata.Add("repository", dist.PortsTree.Repository);
            _pkgmgr.RecordPackage(dist, installer, allfiles, metadata.ToArray());

            if (installer.HasPkgPostInstTarget) {
                _log.Info("Executing post-install tasks...");
                installer.PkgPostInst();
            }

            if (mea.Selected) {
                _log.InfoFormat("Recording {0} in world favourites", dist.Package.FullName);
                _pkgmgr.SelectPackage(dist.Atom);
            }

            _log.Debug("Destroying the sandbox...");
            sbox.Delete();
        }